diff --git a/Gemfile b/Gemfile index a62907b..7bc3434 100644 --- a/Gemfile +++ b/Gemfile @@ -38,7 +38,7 @@ gem "kamal", require: false gem "thruster", require: false # Use Active Storage variants [https://guides.rubyonrails.org/active_storage_overview.html#transforming-images] -# gem "image_processing", "~> 1.2" +gem 'image_processing', '~> 1.12' group :development, :test do # See https://guides.rubyonrails.org/debugging_rails_applications.html#debugging-with-the-debug-gem diff --git a/Gemfile.lock b/Gemfile.lock index 252bb12..c9bf4d8 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -108,6 +108,7 @@ GEM erubi (1.13.1) et-orbi (1.4.0) tzinfo + ffi (1.17.2-x86_64-linux-gnu) fugit (1.11.2) et-orbi (~> 1, >= 1.2.11) raabro (~> 1.4) @@ -115,6 +116,9 @@ GEM activesupport (>= 6.1) i18n (1.14.7) concurrent-ruby (~> 1.0) + image_processing (1.14.0) + mini_magick (>= 4.9.5, < 6) + ruby-vips (>= 2.0.17, < 3) importmap-rails (2.2.2) actionpack (>= 6.0.0) activesupport (>= 6.0.0) @@ -152,6 +156,8 @@ GEM net-smtp marcel (1.1.0) matrix (0.4.3) + mini_magick (5.3.1) + logger mini_mime (1.1.5) minitest (5.25.5) msgpack (1.8.0) @@ -269,6 +275,9 @@ GEM rubocop-performance (>= 1.24) rubocop-rails (>= 2.30) ruby-progressbar (1.13.0) + ruby-vips (2.2.5) + ffi (~> 1.12) + logger rubyzip (3.1.1) securerandom (0.4.1) selenium-webdriver (4.35.0) @@ -340,6 +349,7 @@ DEPENDENCIES brakeman capybara debug + image_processing (~> 1.12) importmap-rails jbuilder kamal diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 0d95db2..8176851 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -1,4 +1,8 @@ class ApplicationController < ActionController::Base # Only allow modern browsers supporting webp images, web push, badges, import maps, CSS nesting, and CSS :has. allow_browser versions: :modern + before_action :set_assets_url + def set_assets_url + Rails.application.routes.default_url_options[:host] = "10.159.208.233:3000" + end end diff --git a/app/controllers/exclusive_traditional_records_controller.rb b/app/controllers/exclusive_traditional_records_controller.rb new file mode 100644 index 0000000..d0d0aad --- /dev/null +++ b/app/controllers/exclusive_traditional_records_controller.rb @@ -0,0 +1,70 @@ +class ExclusiveTraditionalRecordsController < ApplicationController + before_action :set_exclusive_traditional_record, only: %i[ show edit update destroy ] + + # GET /exclusive_traditional_records or /exclusive_traditional_records.json + def index + @exclusive_traditional_records = ExclusiveTraditionalRecord.all + end + + # GET /exclusive_traditional_records/1 or /exclusive_traditional_records/1.json + def show + end + + # GET /exclusive_traditional_records/new + def new + @exclusive_traditional_record = ExclusiveTraditionalRecord.new + end + + # GET /exclusive_traditional_records/1/edit + def edit + end + + # POST /exclusive_traditional_records or /exclusive_traditional_records.json + def create + @exclusive_traditional_record = ExclusiveTraditionalRecord.new(exclusive_traditional_record_params) + + respond_to do |format| + if @exclusive_traditional_record.save + format.html { redirect_to @exclusive_traditional_record, notice: "Exclusive traditional record was successfully created." } + format.json { render :show, status: :created, location: @exclusive_traditional_record } + else + format.html { render :new, status: :unprocessable_entity } + format.json { render json: @exclusive_traditional_record.errors, status: :unprocessable_entity } + end + end + end + + # PATCH/PUT /exclusive_traditional_records/1 or /exclusive_traditional_records/1.json + def update + respond_to do |format| + if @exclusive_traditional_record.update(exclusive_traditional_record_params) + format.html { redirect_to @exclusive_traditional_record, notice: "Exclusive traditional record was successfully updated.", status: :see_other } + format.json { render :show, status: :ok, location: @exclusive_traditional_record } + else + format.html { render :edit, status: :unprocessable_entity } + format.json { render json: @exclusive_traditional_record.errors, status: :unprocessable_entity } + end + end + end + + # DELETE /exclusive_traditional_records/1 or /exclusive_traditional_records/1.json + def destroy + @exclusive_traditional_record.destroy! + + respond_to do |format| + format.html { redirect_to exclusive_traditional_records_path, notice: "Exclusive traditional record was successfully destroyed.", status: :see_other } + format.json { head :no_content } + end + end + + private + # Use callbacks to share common setup or constraints between actions. + def set_exclusive_traditional_record + @exclusive_traditional_record = ExclusiveTraditionalRecord.find(params[:id]) + end + + # Only allow a list of trusted parameters through. + def exclusive_traditional_record_params + params.require(:exclusive_traditional_record).permit(:name, :author, :description, :pdf_file) + end +end diff --git a/app/controllers/expenses_controller.rb b/app/controllers/expenses_controller.rb new file mode 100644 index 0000000..3ecbee2 --- /dev/null +++ b/app/controllers/expenses_controller.rb @@ -0,0 +1,131 @@ +class ExpensesController < ApplicationController + before_action :set_expense, only: %i[ show edit update destroy ] + + # GET /expenses or /expenses.json + def index + @expenses = Expense.all + @expenses = Expense.order(created_at: :desc) + @total_expenses = Expense.sum(:amount) + @daily_expenses = Expense.where(created_at: Time.current.all_day).sum(:amount) + @weekly_expenses = Expense.where(created_at: Time.current.all_week).sum(:amount) + @monthly_expenses = Expense.where(created_at: Time.current.all_month).sum(:amount) + @daily_expense_items = Expense.where(created_at: Time.current.all_day) + @weekly_expense_items = Expense.where(created_at: Time.current.all_week) + @monthly_expense_items = Expense.where(created_at: Time.current.all_month) + end + + # GET /expenses/1 or /expenses/1.json + def show + @expense = Expense.find(params[:id]) + + # Totals + @total_expenses = Expense.sum(:amount) + @daily_expenses = Expense.where(created_at: Time.current.all_day).sum(:amount) + @weekly_expenses = Expense.where(created_at: Time.current.all_week).sum(:amount) + @monthly_expenses = Expense.where(created_at: Time.current.all_month).sum(:amount) + + # Lists + @daily_expense_items = Expense.where(created_at: Time.current.all_day) + @weekly_expense_items = Expense.where(created_at: Time.current.all_week) + @monthly_expense_items = Expense.where(created_at: Time.current.all_month) + end + + # GET /expenses/report + def report + set_summary + render :report + @daily_expense_items = Expense.where(date: Date.today.all_day) + @weekly_expense_items = Expense.where(date: Date.today.beginning_of_week..Date.today.end_of_week) + @monthly_expense_items = Expense.where(date: Date.today.beginning_of_month..Date.today.end_of_month) + + @daily_expenses = @daily_expense_items.sum(:amount) + @weekly_expenses = @weekly_expense_items.sum(:amount) + @monthly_expenses = @monthly_expense_items.sum(:amount) + + # For chart + @chart_labels = @monthly_expense_items.pluck(:date).map { |d| d.strftime("%d %b") } + @chart_data = @monthly_expense_items.pluck(:amount) + end + + # GET /expenses/new + def new + @expense = Expense.new + end + + # GET /expenses/1/edit + def edit + end + + # POST /expenses or /expenses.json + def create + @expense = Expense.new(expense_params) + + respond_to do |format| + if @expense.save + format.html { redirect_to @expense, notice: "Expense was successfully created." } + format.json { render :show, status: :created, location: @expense } + else + format.html { render :new, status: :unprocessable_entity } + format.json { render json: @expense.errors, status: :unprocessable_entity } + end + end + end + + # PATCH/PUT /expenses/1 or /expenses/1.json + def update + respond_to do |format| + if @expense.update(expense_params) + format.html { redirect_to @expense, notice: "Expense was successfully updated.", status: :see_other } + format.json { render :show, status: :ok, location: @expense } + else + format.html { render :edit, status: :unprocessable_entity } + format.json { render json: @expense.errors, status: :unprocessable_entity } + end + end + end + + # DELETE /expenses/1 or /expenses/1.json + def destroy + @expense.destroy! + + respond_to do |format| + format.html { redirect_to expenses_path, notice: "Expense was successfully destroyed.", status: :see_other } + format.json { head :no_content } + end + end + + private + # Use callbacks to share common setup or constraints between actions. + def set_expense + @expense = Expense.find(params[:id]) + end + + # Only allow a list of trusted parameters through. + def expense_params + params.require(:expense).permit(:amount, :date, :description) + end + def set_summary + @total_expenses = Expense.sum(:amount) + @daily_expenses = Expense.where(created_at: Time.current.all_day).sum(:amount) + @weekly_expenses = Expense.where(created_at: Time.current.all_week).sum(:amount) + @monthly_expenses = Expense.where(created_at: Time.current.all_month).sum(:amount) + + @daily_expense_items = Expense.where(created_at: Time.current.all_day) + @weekly_expense_items = Expense.where(created_at: Time.current.all_week) + @monthly_expense_items = Expense.where(created_at: Time.current.all_month) + + # Build chart data for the last 30 days (labels + totals per day) + days_back = 29 + end_date = Date.current + start_date = end_date - days_back + labels = [] + data = [] + (start_date..end_date).each do |d| + labels << d.strftime("%d %b") + day_total = Expense.where(created_at: d.beginning_of_day..d.end_of_day).sum(:amount) + data << day_total + end + @chart_labels = labels + @chart_data = data + end +end diff --git a/app/controllers/incomes_controller.rb b/app/controllers/incomes_controller.rb new file mode 100644 index 0000000..b635c18 --- /dev/null +++ b/app/controllers/incomes_controller.rb @@ -0,0 +1,91 @@ +class IncomesController < ApplicationController + before_action :set_income, only: %i[ show edit update destroy ] + + # GET /incomes + def index + @incomes = Income.all + end + + # GET /incomes/report + def report + # @incomes = Income.all + + # # Group incomes + # @daily_income = @incomes.where(date: Date.today).sum(:amount) + # @weekly_income = @incomes.where(date: Date.today.beginning_of_week..Date.today.end_of_week).sum(:amount) + # @monthly_income = @incomes.where(date: Date.today.beginning_of_month..Date.today.end_of_month).sum(:amount) + + # # List items + # @daily_income_items = @incomes.where(date: Date.today) + # @weekly_income_items = @incomes.where(date: Date.today.beginning_of_week..Date.today.end_of_week) + # @monthly_income_items = @incomes.where(date: Date.today.beginning_of_month..Date.today.end_of_month) + + # # Chart (Group by Month) + # grouped = @incomes.group_by { |i| i.date.strftime("%b") } + # @chart_labels = grouped.keys + # @chart_data = grouped.values.map { |items| items.sum(&:amount) } + @incomes = Income.all + + # Daily / Weekly / Monthly totals using scopes + @daily_income = Income.today.total_amount + @weekly_income = Income.this_week.total_amount + @monthly_income = Income.this_month.total_amount + + # For charts + @chart_labels = (0..6).map { |i| (Date.today - i).strftime("%d %b") }.reverse + @chart_data = @chart_labels.map { |d| Income.where(created_at: d.to_date.all_day).sum(:amount) } + end + + def show; end + + def new + @income = Income.new + end + + def edit; end + + def create + @income = Income.new(income_params) + + respond_to do |format| + if @income.save + format.html { redirect_to @income, notice: "Income was successfully created." } + format.json { render :show, status: :created, location: @income } + else + format.html { render :new, status: :unprocessable_entity } + format.json { render json: @income.errors, status: :unprocessable_entity } + end + end + end + + def update + respond_to do |format| + if @income.update(income_params) + format.html { redirect_to @income, notice: "Income was successfully updated.", status: :see_other } + format.json { render :show, status: :ok, location: @income } + else + format.html { render :edit, status: :unprocessable_entity } + format.json { render json: @income.errors, status: :unprocessable_entity } + end + end + end + + def destroy + @income.destroy! + + respond_to do |format| + format.html { redirect_to incomes_path, notice: "Income was successfully destroyed.", status: :see_other } + format.json { head :no_content } + end + end + + private + + def set_income + @income = Income.find(params[:id]) + end + + def income_params + params.require(:income).permit(:title, :amount, :date, :category, :description) + end +end diff --git a/app/controllers/institutions_controller.rb b/app/controllers/institutions_controller.rb index 636870d..0e0cfbc 100644 --- a/app/controllers/institutions_controller.rb +++ b/app/controllers/institutions_controller.rb @@ -2,17 +2,58 @@ class InstitutionsController < ApplicationController before_action :set_institution, only: %i[ show edit update destroy ] + # GET /institutions or /institutions.json def index + @incomes = Income.all @institutions = Institution.all @programs = Program.all @ziyaras = Ziyara.all + @students = Student.all + @institution_count = Institution.count + @program_count = Program.count + @student_count = Student.count + @ziyara_count = Ziyara.count + + @institutions = Institution.all + @programs = Program.all + @ziyaras = Ziyara.all + @exclusive_traditional_records = ExclusiveTraditionalRecord.all + @exclusive_traditional_records_count = ExclusiveTraditionalRecord.count + @expenses = Expense.all + @expenses = Expense.order(created_at: :desc) + + # Totals + @total_expenses = Expense.sum(:amount) + @daily_expenses = Expense.where(created_at: Time.current.all_day).sum(:amount) + @weekly_expenses = Expense.where(created_at: Time.current.all_week).sum(:amount) + @monthly_expenses = Expense.where(created_at: Time.current.all_month).sum(:amount) + + # Expense lists (MUST be here) + @daily_expense_items = Expense.where(created_at: Time.current.all_day) + @weekly_expense_items = Expense.where(created_at: Time.current.all_week) + @monthly_expense_items = Expense.where(created_at: Time.current.all_month) + + + # index is a collection action β€” do not attempt to load a single institution here + @students = Student.all + end + # Use callbacks to share common setup or constraints between actions. + def set_institution + @institution = Institution.find_by(id: params[:institution_id]) + end + + # GET /institutions/1 or /institutions/1.json def show end + # GET /institutions/contact + def contact + end + # GET /institutions/new def new @institution = Institution.new @@ -63,11 +104,13 @@ class InstitutionsController < ApplicationController private # Use callbacks to share common setup or constraints between actions. def set_institution - @institution = Institution.find(params.expect(:id)) + @institution = Institution.find(params[:id]) end # Only allow a list of trusted parameters through. def institution_params - params.expect(institution: [ :name, :institution_type, :place ]) + params.require(:institution).permit(:name, :institution_type, :place) end + + end diff --git a/app/controllers/programs_controller.rb b/app/controllers/programs_controller.rb index 56a1872..6905a3c 100644 --- a/app/controllers/programs_controller.rb +++ b/app/controllers/programs_controller.rb @@ -60,11 +60,11 @@ class ProgramsController < ApplicationController private # Use callbacks to share common setup or constraints between actions. def set_program - @program = Program.find(params.expect(:id)) + @program = Program.find(params[:id]) end # Only allow a list of trusted parameters through. def program_params - params.expect(program: [ :name, :date, :leadingPerson ]) + params.require(:program).permit(:name, :date, :leadingPerson, :description) end end diff --git a/app/controllers/students_controller.rb b/app/controllers/students_controller.rb index cdb69f3..2929b0f 100644 --- a/app/controllers/students_controller.rb +++ b/app/controllers/students_controller.rb @@ -1,10 +1,19 @@ class StudentsController < ApplicationController + # set_institution will try to load an institution when institution_id is present before_action :set_institution + # set_student will safely find a student either scoped to @institution or globally before_action :set_student, only: %i[ show edit update destroy ] + # ensure nested behaviour for index/new/create (these expect an institution) + before_action :ensure_institution_for_nested_actions, only: %i[index new create] # GET /students or /students.json def index - @students = @institution.students + if @institution + @students = @institution.students + else + # show all students when not nested + @students = Student.all + end end # GET /students/1 or /students/1.json @@ -21,14 +30,28 @@ class StudentsController < ApplicationController end # POST /students or /students.json + # def create + # @student = @institution.students.build(student_params) + # if @student.save + # redirect_to institution_students_path(@institution), notice: 'Student was successfully created.' + # else + # render :new, status: :unprocessable_entity + # end + # end def create - @student = @institution.students.build(student_params) - if @student.save - redirect_to institution_students_path(@institution), notice: 'Student was successfully created.' - else - render :new, status: :unprocessable_entity + @student = @institution.students.new(student_params) + + if @student.save + respond_to do |format| + format.js # creates -> create.js.erb + end + else + respond_to do |format| + format.js { render :error } end end + end + # PATCH/PUT /students/1 or /students/1.json def update @@ -48,15 +71,33 @@ class StudentsController < ApplicationController private # Use callbacks to share common setup or constraints between actions. def set_institution + return unless params[:institution_id].present? @institution = Institution.find(params[:institution_id]) + rescue ActiveRecord::RecordNotFound + # Let other parts handle missing institution (redirects in actions) + @institution = nil end def set_student - @student = @institution.students.find(params[:id]) + if @institution.present? + @student = @institution.students.find(params[:id]) + else + # fallback to global lookup when not nested + @student = Student.find(params[:id]) if params[:id].present? + @institution = @student.institution if @student.present? + end + rescue ActiveRecord::RecordNotFound + # will raise in actions if record missing + raise + end + + def ensure_institution_for_nested_actions + return if @institution.present? + redirect_to institutions_path, alert: 'Please select an Institution first.' end # Only allow a list of trusted parameters through. def student_params - params.require(:student).permit(:first_name, :last_name, :email, :institution_id) + params.require(:student).permit(:first_name, :last_name, :email, :institution_id, :place, :phone_number, :age, :photo) end end diff --git a/app/controllers/ziyaras_controller.rb b/app/controllers/ziyaras_controller.rb index 9eba6ee..6bdf32c 100644 --- a/app/controllers/ziyaras_controller.rb +++ b/app/controllers/ziyaras_controller.rb @@ -60,11 +60,11 @@ class ZiyarasController < ApplicationController private # Use callbacks to share common setup or constraints between actions. def set_ziyara - @ziyara = Ziyara.find(params.expect(:id)) + @ziyara = Ziyara.find(params[:id]) end # Only allow a list of trusted parameters through. def ziyara_params - params.expect(ziyara: [ :name ]) + params.require(:ziyara).permit(:name, :date, :location, :description) end end diff --git a/app/helpers/exclusive_traditional_records_helper.rb b/app/helpers/exclusive_traditional_records_helper.rb new file mode 100644 index 0000000..0b51216 --- /dev/null +++ b/app/helpers/exclusive_traditional_records_helper.rb @@ -0,0 +1,2 @@ +module ExclusiveTraditionalRecordsHelper +end diff --git a/app/helpers/expenses_helper.rb b/app/helpers/expenses_helper.rb new file mode 100644 index 0000000..1d50062 --- /dev/null +++ b/app/helpers/expenses_helper.rb @@ -0,0 +1,2 @@ +module ExpensesHelper +end diff --git a/app/helpers/incomes_helper.rb b/app/helpers/incomes_helper.rb new file mode 100644 index 0000000..4f2262e --- /dev/null +++ b/app/helpers/incomes_helper.rb @@ -0,0 +1,2 @@ +module IncomesHelper +end diff --git a/app/models/exclusive_traditional_record.rb b/app/models/exclusive_traditional_record.rb new file mode 100644 index 0000000..a506565 --- /dev/null +++ b/app/models/exclusive_traditional_record.rb @@ -0,0 +1,3 @@ +class ExclusiveTraditionalRecord < ApplicationRecord + has_one_attached :pdf_file +end diff --git a/app/models/expense.rb b/app/models/expense.rb new file mode 100644 index 0000000..3015508 --- /dev/null +++ b/app/models/expense.rb @@ -0,0 +1,8 @@ +class Expense < ApplicationRecord + scope :today, -> { where(created_at: Time.current.all_day) } + scope :this_week, -> { where(created_at: Time.current.all_week) } + scope :this_month, -> { where(created_at: Time.current.all_month) } + + validates :amount, presence: true, numericality: { greater_than_or_equal_to: 0 } + validates :date, presence: true +end diff --git a/app/models/income.rb b/app/models/income.rb new file mode 100644 index 0000000..2ea4bb1 --- /dev/null +++ b/app/models/income.rb @@ -0,0 +1,13 @@ +class Income < ApplicationRecord + # Today’s income + scope :today, -> { where("created_at >= ?", Time.zone.now.beginning_of_day) } + + # This week income + scope :this_week, -> { where(created_at: Time.zone.now.beginning_of_week..Time.zone.now.end_of_week) } + + # This month income + scope :this_month, -> { where(created_at: Time.zone.now.beginning_of_month..Time.zone.now.end_of_month) } + + # Optional: total amount + scope :total_amount, -> { sum(:amount) } +end diff --git a/app/models/student.rb b/app/models/student.rb index a0c4969..dd27047 100644 --- a/app/models/student.rb +++ b/app/models/student.rb @@ -1,3 +1,4 @@ class Student < ApplicationRecord belongs_to :institution + has_one_attached :photo end diff --git a/app/views/exclusive_traditional_records/_exclusive_traditional_record.html.erb b/app/views/exclusive_traditional_records/_exclusive_traditional_record.html.erb new file mode 100644 index 0000000..28bdfbe --- /dev/null +++ b/app/views/exclusive_traditional_records/_exclusive_traditional_record.html.erb @@ -0,0 +1,26 @@ +
+

+ Name: + <%= exclusive_traditional_record.name %> +

+ +

+ Author: + <%= exclusive_traditional_record.author %> +

+ +

+ Description: + <%= exclusive_traditional_record.description %> +

+ +
+ <% if exclusive_traditional_record.pdf_file.attached? %> + PDF File: + <%= link_to exclusive_traditional_record.pdf_file.filename.to_s, rails_blob_path(exclusive_traditional_record.pdf_file, disposition: "attachment") %> + <% else %> + No PDF file uploaded. + <% end %> +
+ +
diff --git a/app/views/exclusive_traditional_records/_exclusive_traditional_record.json.jbuilder b/app/views/exclusive_traditional_records/_exclusive_traditional_record.json.jbuilder new file mode 100644 index 0000000..aeab4ff --- /dev/null +++ b/app/views/exclusive_traditional_records/_exclusive_traditional_record.json.jbuilder @@ -0,0 +1,2 @@ +json.extract! exclusive_traditional_record, :id, :name, :author, :description, :created_at, :updated_at +json.url exclusive_traditional_record_url(exclusive_traditional_record, format: :json) diff --git a/app/views/exclusive_traditional_records/_form.html.erb b/app/views/exclusive_traditional_records/_form.html.erb new file mode 100644 index 0000000..e13d1db --- /dev/null +++ b/app/views/exclusive_traditional_records/_form.html.erb @@ -0,0 +1,37 @@ +<%= form_with(model: exclusive_traditional_record) do |form| %> + <% if exclusive_traditional_record.errors.any? %> +
+

<%= pluralize(exclusive_traditional_record.errors.count, "error") %> prohibited this exclusive_traditional_record from being saved:

+ + +
+ <% end %> + +
+ <%= form.label :name, style: "display: block" %> + <%= form.text_field :name %> +
+ +
+ <%= form.label :author, style: "display: block" %> + <%= form.text_field :author %> +
+ +
+ <%= form.label :description, style: "display: block" %> + <%= form.textarea :description %> +
+ +
+ <%= form.label :pdf_file, "Upload PDF", style: "display: block" %> + <%= form.file_field :pdf_file %> +
+ +
+ <%= form.submit %> +
+<% end %> diff --git a/app/views/exclusive_traditional_records/edit.html.erb b/app/views/exclusive_traditional_records/edit.html.erb new file mode 100644 index 0000000..d9b1b2e --- /dev/null +++ b/app/views/exclusive_traditional_records/edit.html.erb @@ -0,0 +1,12 @@ +<% content_for :title, "Editing exclusive traditional record" %> + +

Editing exclusive traditional record

+ +<%= render "form", exclusive_traditional_record: @exclusive_traditional_record %> + +
+ +
+ <%= link_to "Show this exclusive traditional record", @exclusive_traditional_record %> | + <%= link_to "Back to exclusive traditional records", exclusive_traditional_records_path %> +
diff --git a/app/views/exclusive_traditional_records/index.html.erb b/app/views/exclusive_traditional_records/index.html.erb new file mode 100644 index 0000000..6053481 --- /dev/null +++ b/app/views/exclusive_traditional_records/index.html.erb @@ -0,0 +1,16 @@ +

<%= notice %>

+ +<% content_for :title, "Exclusive traditional records" %> + +

Exclusive traditional records

+ +
+ <% @exclusive_traditional_records.each do |exclusive_traditional_record| %> + <%= render exclusive_traditional_record %> +

+ <%= link_to "Show this exclusive traditional record", exclusive_traditional_record %> +

+ <% end %> +
+ +<%= link_to "New exclusive traditional record", new_exclusive_traditional_record_path %> diff --git a/app/views/exclusive_traditional_records/index.json.jbuilder b/app/views/exclusive_traditional_records/index.json.jbuilder new file mode 100644 index 0000000..34b9c09 --- /dev/null +++ b/app/views/exclusive_traditional_records/index.json.jbuilder @@ -0,0 +1 @@ +json.array! @exclusive_traditional_records, partial: "exclusive_traditional_records/exclusive_traditional_record", as: :exclusive_traditional_record diff --git a/app/views/exclusive_traditional_records/new.html.erb b/app/views/exclusive_traditional_records/new.html.erb new file mode 100644 index 0000000..325daec --- /dev/null +++ b/app/views/exclusive_traditional_records/new.html.erb @@ -0,0 +1,11 @@ +<% content_for :title, "New exclusive traditional record" %> + +

New exclusive traditional record

+ +<%= render "form", exclusive_traditional_record: @exclusive_traditional_record %> + +
+ +
+ <%= link_to "Back to exclusive traditional records", exclusive_traditional_records_path %> +
diff --git a/app/views/exclusive_traditional_records/show.html.erb b/app/views/exclusive_traditional_records/show.html.erb new file mode 100644 index 0000000..c1e571b --- /dev/null +++ b/app/views/exclusive_traditional_records/show.html.erb @@ -0,0 +1,10 @@ +

<%= notice %>

+ +<%= render @exclusive_traditional_record %> + +
+ <%= link_to "Edit this exclusive traditional record", edit_exclusive_traditional_record_path(@exclusive_traditional_record) %> | + <%= link_to "Back to exclusive traditional records", exclusive_traditional_records_path %> + + <%= button_to "Destroy this exclusive traditional record", @exclusive_traditional_record, method: :delete %> +
diff --git a/app/views/exclusive_traditional_records/show.json.jbuilder b/app/views/exclusive_traditional_records/show.json.jbuilder new file mode 100644 index 0000000..14c699d --- /dev/null +++ b/app/views/exclusive_traditional_records/show.json.jbuilder @@ -0,0 +1 @@ +json.partial! "exclusive_traditional_records/exclusive_traditional_record", exclusive_traditional_record: @exclusive_traditional_record diff --git a/app/views/expenses/_expense.html.erb b/app/views/expenses/_expense.html.erb new file mode 100644 index 0000000..8479fd5 --- /dev/null +++ b/app/views/expenses/_expense.html.erb @@ -0,0 +1,12 @@ +
+

+ Amount: + <%= expense.amount %> +

+ +

+ Date: + <%= expense.date %> +

+ +
diff --git a/app/views/expenses/_expense.json.jbuilder b/app/views/expenses/_expense.json.jbuilder new file mode 100644 index 0000000..e0dba8b --- /dev/null +++ b/app/views/expenses/_expense.json.jbuilder @@ -0,0 +1,2 @@ +json.extract! expense, :id, :amount, :date, :created_at, :updated_at +json.url expense_url(expense, format: :json) diff --git a/app/views/expenses/_form.html.erb b/app/views/expenses/_form.html.erb new file mode 100644 index 0000000..36dc677 --- /dev/null +++ b/app/views/expenses/_form.html.erb @@ -0,0 +1,27 @@ +<%= form_with(model: expense) do |form| %> + <% if expense.errors.any? %> +
+

<%= pluralize(expense.errors.count, "error") %> prohibited this expense from being saved:

+ + +
+ <% end %> + +
+ <%= form.label :amount, style: "display: block" %> + <%= form.text_field :amount %> +
+ +
+ <%= form.label :date, style: "display: block" %> + <%= form.date_field :date %> +
+ +
+ <%= form.submit %> +
+<% end %> diff --git a/app/views/expenses/edit.html.erb b/app/views/expenses/edit.html.erb new file mode 100644 index 0000000..68e6139 --- /dev/null +++ b/app/views/expenses/edit.html.erb @@ -0,0 +1,12 @@ +<% content_for :title, "Editing expense" %> + +

Editing expense

+ +<%= render "form", expense: @expense %> + +
+ +
+ <%= link_to "Show this expense", @expense %> | + <%= link_to "Back to expenses", expenses_path %> +
diff --git a/app/views/expenses/index.html.erb b/app/views/expenses/index.html.erb new file mode 100644 index 0000000..14c13ce --- /dev/null +++ b/app/views/expenses/index.html.erb @@ -0,0 +1,104 @@ +

<%= notice %>

+ +<% content_for :title, "Expenses" %> + +

Expenses

+
+ <%= link_to "πŸ“Š Expense Report", expense_report_path, class: "btn btn-outline-primary" %> +
+ + + +<%= link_to "New Expense", new_expense_path, class: "btn-expense" %> + + +
+ <% @expenses.each do |expense| %> +
+
<%= number_to_currency(expense.amount) %>
+
<%= expense.created_at.strftime("%d %b %Y") %>
+ <%= link_to "Show this expense", expense, class: "show-link" %> +
+ <% end %> +
+ + diff --git a/app/views/expenses/index.json.jbuilder b/app/views/expenses/index.json.jbuilder new file mode 100644 index 0000000..68cd3c6 --- /dev/null +++ b/app/views/expenses/index.json.jbuilder @@ -0,0 +1 @@ +json.array! @expenses, partial: "expenses/expense", as: :expense diff --git a/app/views/expenses/new.html.erb b/app/views/expenses/new.html.erb new file mode 100644 index 0000000..d6b52f1 --- /dev/null +++ b/app/views/expenses/new.html.erb @@ -0,0 +1,11 @@ +<% content_for :title, "New expense" %> + +

New expense

+ +<%= render "form", expense: @expense %> + +
+ +
+ <%= link_to "Back to expenses", expenses_path %> +
diff --git a/app/views/expenses/report.html.erb b/app/views/expenses/report.html.erb new file mode 100644 index 0000000..81714e5 --- /dev/null +++ b/app/views/expenses/report.html.erb @@ -0,0 +1,284 @@ +<% content_for :title, "Expense Report" %> + + + + +
+
+

EXPENSE REPORT

+ +
+ <%= link_to "New Expense", new_expense_path, class: "btn-simple" %> +
+
+ + +
+
+ Today's Expenses +
<%= number_to_currency(@daily_expenses || 0, unit: "β‚Ή") %>
+
+ +
+ This Week +
<%= number_to_currency(@weekly_expenses || 0, unit: "β‚Ή") %>
+
+ +
+ This Month +
<%= number_to_currency(@monthly_expenses || 0, unit: "β‚Ή") %>
+
+
+ + +
+ +
+ + +
+

Today's Expenses

+ + + + + + <% (@daily_expense_items || []).each do |expense| %> + + + + + <% end %> + <% if (@daily_expense_items || []).empty? %> + + <% end %> + + + + +
AmountDate
<%= number_to_currency(expense.amount, unit: "β‚Ή") %><%= expense.created_at.strftime("%d %b %Y") %>
No expenses for today.
Total<%= number_to_currency(@daily_expenses || 0, unit: "β‚Ή") %>
+
+ + +
+

This Week's Expenses

+ + + + + + <% (@weekly_expense_items || []).each do |expense| %> + + + + + <% end %> + <% if (@weekly_expense_items || []).empty? %> + + <% end %> + + + + +
AmountDate
<%= number_to_currency(expense.amount, unit: "β‚Ή") %><%= expense.created_at.strftime("%d %b %Y") %>
No expenses for this week.
Total<%= number_to_currency(@weekly_expenses || 0, unit: "β‚Ή") %>
+
+ + +
+

This Month's Expenses

+ + + + + + <% (@monthly_expense_items || []).each do |expense| %> + + + + + <% end %> + <% if (@monthly_expense_items || []).empty? %> + + <% end %> + + + + +
AmountDate
<%= number_to_currency(expense.amount, unit: "β‚Ή") %><%= expense.created_at.strftime("%d %b %Y") %>
No expenses for this month.
Total<%= number_to_currency(@monthly_expenses || 0, unit: "β‚Ή") %>
+
+
+ + + + +<% content_for :title, "Expense Report" %> + diff --git a/app/views/expenses/show.html.erb b/app/views/expenses/show.html.erb new file mode 100644 index 0000000..620b6c5 --- /dev/null +++ b/app/views/expenses/show.html.erb @@ -0,0 +1,11 @@ +

<%= notice %>

+ +<%= render @expense %> + +
+ <%= link_to "Edit this expense", edit_expense_path(@expense) %> | + <%= link_to "Back to expenses", expenses_path %> + + <%= button_to "Destroy this expense", @expense, method: :delete %> +
+ diff --git a/app/views/expenses/show.json.jbuilder b/app/views/expenses/show.json.jbuilder new file mode 100644 index 0000000..3bb3176 --- /dev/null +++ b/app/views/expenses/show.json.jbuilder @@ -0,0 +1 @@ +json.partial! "expenses/expense", expense: @expense diff --git a/app/views/incomes/_form.html.erb b/app/views/incomes/_form.html.erb new file mode 100644 index 0000000..0cab65a --- /dev/null +++ b/app/views/incomes/_form.html.erb @@ -0,0 +1,42 @@ +<%= form_with(model: income) do |form| %> + <% if income.errors.any? %> +
+

<%= pluralize(income.errors.count, "error") %> prohibited this income from being saved:

+ + +
+ <% end %> + +
+ <%= form.label :title, style: "display: block" %> + <%= form.text_field :title %> +
+ +
+ <%= form.label :amount, style: "display: block" %> + <%= form.text_field :amount %> +
+ +
+ <%= form.label :date, style: "display: block" %> + <%= form.date_field :date %> +
+ +
+ <%= form.label :category, style: "display: block" %> + <%= form.text_field :category %> +
+ +
+ <%= form.label :description, style: "display: block" %> + <%= form.textarea :description %> +
+ +
+ <%= form.submit %> +
+<% end %> diff --git a/app/views/incomes/_income.html.erb b/app/views/incomes/_income.html.erb new file mode 100644 index 0000000..188ef8d --- /dev/null +++ b/app/views/incomes/_income.html.erb @@ -0,0 +1,27 @@ +
+

+ Title: + <%= income.title %> +

+ +

+ Amount: + <%= income.amount %> +

+ +

+ Date: + <%= income.date %> +

+ +

+ Category: + <%= income.category %> +

+ +

+ Description: + <%= income.description %> +

+ +
diff --git a/app/views/incomes/_income.json.jbuilder b/app/views/incomes/_income.json.jbuilder new file mode 100644 index 0000000..1546c66 --- /dev/null +++ b/app/views/incomes/_income.json.jbuilder @@ -0,0 +1,2 @@ +json.extract! income, :id, :title, :amount, :date, :category, :description, :created_at, :updated_at +json.url income_url(income, format: :json) diff --git a/app/views/incomes/edit.html.erb b/app/views/incomes/edit.html.erb new file mode 100644 index 0000000..8108bb8 --- /dev/null +++ b/app/views/incomes/edit.html.erb @@ -0,0 +1,12 @@ +<% content_for :title, "Editing income" %> + +

Editing income

+ +<%= render "form", income: @income %> + +
+ +
+ <%= link_to "Show this income", @income %> | + <%= link_to "Back to incomes", incomes_path %> +
diff --git a/app/views/incomes/index.html.erb b/app/views/incomes/index.html.erb new file mode 100644 index 0000000..944d305 --- /dev/null +++ b/app/views/incomes/index.html.erb @@ -0,0 +1,103 @@ +

<%= notice %>

+ +<% content_for :title, "Incomes" %> + +

Incomes

+ +
+ <%= link_to "πŸ“Š Income Report", income_report_path, class: "btn btn-outline-primary" %> +
+ +<%= link_to "New income", new_income_path, class:"btn-income" %> + + +
+ <% @incomes.each do |income| %> +
+
<%= number_to_currency(income.amount) %>
+
<%= income.created_at.strftime("%d %b %Y") %>
+ <%= link_to "Show this income", income, class: "show-link" %> +
+ <% end %> +
+ + \ No newline at end of file diff --git a/app/views/incomes/index.json.jbuilder b/app/views/incomes/index.json.jbuilder new file mode 100644 index 0000000..f8697c9 --- /dev/null +++ b/app/views/incomes/index.json.jbuilder @@ -0,0 +1 @@ +json.array! @incomes, partial: "incomes/income", as: :income diff --git a/app/views/incomes/new.html.erb b/app/views/incomes/new.html.erb new file mode 100644 index 0000000..bd0e178 --- /dev/null +++ b/app/views/incomes/new.html.erb @@ -0,0 +1,11 @@ +<% content_for :title, "New income" %> + +

New income

+ +<%= render "form", income: @income %> + +
+ +
+ <%= link_to "Back to incomes", incomes_path %> +
diff --git a/app/views/incomes/report.html.erb b/app/views/incomes/report.html.erb new file mode 100644 index 0000000..2f1648d --- /dev/null +++ b/app/views/incomes/report.html.erb @@ -0,0 +1,273 @@ +<% content_for :title, "Income Report" %> + + + +
+
+

INCOME REPORT

+ +
+ <%= link_to "New Income", new_income_path, class: "btn-simple" %> +
+
+ + +
+
+ Today's Income +
<%= number_to_currency(@daily_income || 0, unit: "β‚Ή") %>
+
+ +
+ This Week +
<%= number_to_currency(@weekly_income || 0, unit: "β‚Ή") %>
+
+ +
+ This Month +
<%= number_to_currency(@monthly_income || 0, unit: "β‚Ή") %>
+
+
+ + +
+ +
+ + +
+

Today's Income

+ + + + + + <% (@daily_income_items || []).each do |income| %> + + + + + <% end %> + <% if (@daily_income_items || []).empty? %> + + <% end %> + + + + +
AmountDate
<%= number_to_currency(income.amount, unit: "β‚Ή") %><%= income.created_at.strftime("%d %b %Y") %>
No income for today.
Total<%= number_to_currency(@daily_income || 0, unit: "β‚Ή") %>
+
+ + +
+

This Week's Income

+ + + + + + <% (@weekly_income_items || []).each do |income| %> + + + + + <% end %> + <% if (@weekly_income_items || []).empty? %> + + <% end %> + + + + +
AmountDate
<%= number_to_currency(income.amount, unit: "β‚Ή") %><%= income.created_at.strftime("%d %b %Y") %>
No income for this week.
Total<%= number_to_currency(@weekly_income || 0, unit: "β‚Ή") %>
+
+ + +
+

This Month's Income

+ + + + + + <% (@monthly_income_items || []).each do |income| %> + + + + + <% end %> + <% if (@monthly_income_items || []).empty? %> + + <% end %> + + + + +
AmountDate
<%= number_to_currency(income.amount, unit: "β‚Ή") %><%= income.created_at.strftime("%d %b %Y") %>
No income for this month.
Total<%= number_to_currency(@monthly_income || 0, unit: "β‚Ή") %>
+
+
+ + + + diff --git a/app/views/incomes/show.html.erb b/app/views/incomes/show.html.erb new file mode 100644 index 0000000..cf88233 --- /dev/null +++ b/app/views/incomes/show.html.erb @@ -0,0 +1,10 @@ +

<%= notice %>

+ +<%= render @income %> + +
+ <%= link_to "Edit this income", edit_income_path(@income) %> | + <%= link_to "Back to incomes", incomes_path %> + + <%= button_to "Destroy this income", @income, method: :delete %> +
diff --git a/app/views/incomes/show.json.jbuilder b/app/views/incomes/show.json.jbuilder new file mode 100644 index 0000000..f2b0001 --- /dev/null +++ b/app/views/incomes/show.json.jbuilder @@ -0,0 +1 @@ +json.partial! "incomes/income", income: @income diff --git a/app/views/institutions/contact.html.erb b/app/views/institutions/contact.html.erb new file mode 100644 index 0000000..ce0e8ce --- /dev/null +++ b/app/views/institutions/contact.html.erb @@ -0,0 +1,10 @@ +

Contact Us

+

If you have any questions or need assistance, please feel free to reach out to us:

+ \ No newline at end of file diff --git a/app/views/institutions/index.html.erb b/app/views/institutions/index.html.erb index 5cddb3e..ee92300 100644 --- a/app/views/institutions/index.html.erb +++ b/app/views/institutions/index.html.erb @@ -1,230 +1,253 @@
-
- -