├── log └── .keep ├── tmp └── .keep ├── vendor └── .keep ├── docs ├── .nojekyll ├── assets │ ├── db.png │ ├── logo.png │ ├── zen.gif │ ├── colors.png │ ├── heroe.gif │ ├── ui_sample.PNG │ └── street_cat.jpg ├── _coverpage.md ├── _sidebar.md ├── pundit.md ├── slack.md ├── features.md ├── design.md ├── beginners.md ├── mission.md ├── branding.md ├── index.html ├── i18n.md ├── home.md ├── installation.md ├── learning.md ├── conventions.md ├── README.md └── database.md ├── lib ├── assets │ └── .keep └── tasks │ ├── .keep │ └── cleanup.rake ├── public ├── favicon.ico ├── apple-touch-icon.png ├── apple-touch-icon-precomposed.png ├── capa.gif ├── dona.gif ├── dona.png ├── logo.png ├── zen.gif ├── zen.png ├── Standar.png ├── adopta.gif ├── adopta.png ├── ciudad.png ├── corazon.png ├── medalla.png ├── plagas.png ├── adorables.gif ├── adorables.png ├── apadrina.gif ├── apadrina.png ├── explorar.gif ├── explorar.png ├── instagram.png ├── seguridad.png ├── sociable.png ├── street_cat.jpg ├── robots.txt ├── 500.html ├── 422.html ├── 404.html ├── top.svg └── instagram.svg ├── app ├── assets │ ├── images │ │ └── .keep │ ├── javascripts │ │ ├── channels │ │ │ └── .keep │ │ ├── cats.coffee │ │ ├── pages.coffee │ │ ├── turns.coffee │ │ ├── illnesses.coffee │ │ ├── locations.coffee │ │ ├── sufferings.coffee │ │ ├── task_user_wizard.coffee │ │ ├── treatment_entries.coffee │ │ ├── cable.js │ │ └── application.js │ ├── config │ │ └── manifest.js │ └── stylesheets │ │ ├── cats.scss │ │ ├── turns.scss │ │ ├── pages.scss │ │ ├── illnesses.scss │ │ ├── locations.scss │ │ ├── sufferings.scss │ │ ├── task_user_wizard.scss │ │ └── treatment_entries.scss ├── models │ ├── concerns │ │ └── .keep │ ├── turns_user.rb │ ├── application_record.rb │ ├── colonies_user.rb │ ├── assignment.rb │ ├── adoption.rb │ ├── posession.rb │ ├── turn.rb │ ├── donation.rb │ ├── suffering.rb │ ├── task.rb │ ├── product.rb │ ├── treatment_entry.rb │ ├── illness.rb │ ├── sponsor.rb │ ├── colony.rb │ ├── user.rb │ └── cat.rb ├── controllers │ ├── concerns │ │ └── .keep │ ├── pages_controller.rb │ ├── application_controller.rb │ ├── tasks_controller.rb │ ├── assignments_controller.rb │ ├── task_user_wizard_controller.rb │ ├── colonies_controller.rb │ ├── locations_controller.rb │ ├── cats │ │ └── build_controller.rb │ ├── turns_controller.rb │ ├── illnesses_controller.rb │ ├── sufferings_controller.rb │ ├── treatment_entries_controller.rb │ └── cats_controller.rb ├── views │ ├── layouts │ │ ├── mailer.text.erb │ │ ├── mailer.html.erb │ │ ├── application.html.erb │ │ └── pages.html.erb │ ├── tasks │ │ ├── edit.html.erb │ │ ├── new.html.erb │ │ ├── show.html.erb │ │ ├── _form.html.erb │ │ └── index.html.erb │ ├── colonies │ │ ├── edit.html.erb │ │ ├── new.html.erb │ │ ├── destroy.html.erb │ │ ├── index.html.erb │ │ ├── _form.html.erb │ │ └── show.html.erb │ ├── illnesses │ │ ├── create.html.erb │ │ ├── update.html.erb │ │ ├── destroy.html.erb │ │ ├── index.html.erb │ │ ├── show.html.erb │ │ ├── edit.html.erb │ │ └── new.html.erb │ ├── locations │ │ ├── destroy.html.erb │ │ ├── index.html.erb │ │ ├── show.html.erb │ │ ├── edit.html.erb │ │ └── new.html.erb │ ├── cats │ │ ├── adopt.html.erb │ │ ├── build │ │ │ ├── add_origin.html.erb │ │ │ ├── has_been_to_vet.html.erb │ │ │ ├── add_bio.html.erb │ │ │ ├── finish.html.erb │ │ │ ├── add_abandoned_date.html.erb │ │ │ ├── add_colony.erb │ │ │ ├── add_vet_info.html.erb │ │ │ ├── add_basic_info.html.erb │ │ │ ├── _suffering_fields.html.erb │ │ │ └── add_illnesses.html.erb │ │ ├── new_sponsor.html.erb │ │ ├── new.html.erb │ │ ├── index.html.erb │ │ ├── show.html.erb │ │ └── edit.html.erb │ ├── devise │ │ ├── mailer │ │ │ ├── password_change.html.erb │ │ │ ├── confirmation_instructions.html.erb │ │ │ ├── unlock_instructions.html.erb │ │ │ ├── email_changed.html.erb │ │ │ └── reset_password_instructions.html.erb │ │ ├── unlocks │ │ │ └── new.html.erb │ │ ├── passwords │ │ │ ├── new.html.erb │ │ │ └── edit.html.erb │ │ ├── confirmations │ │ │ └── new.html.erb │ │ ├── sessions │ │ │ └── new.html.erb │ │ ├── shared │ │ │ └── _links.html.erb │ │ └── registrations │ │ │ ├── new.html.erb │ │ │ └── edit.html.erb │ ├── assignments │ │ ├── new.html.erb │ │ └── index.html.erb │ ├── turns │ │ ├── edit.html.erb │ │ ├── new.html.erb │ │ └── index.html.erb │ ├── treatment_entries │ │ ├── show.html.erb │ │ ├── edit.html.erb │ │ ├── new.html.erb │ │ └── index.html.erb │ ├── sufferings │ │ ├── edit.html.erb │ │ ├── new.html.erb │ │ ├── show.html.erb │ │ └── index.html.erb │ ├── task_user_wizard │ │ └── new.html.erb │ └── pages │ │ ├── learn.html.erb │ │ ├── work.html.erb │ │ └── league.html.erb ├── helpers │ ├── cats_helper.rb │ ├── pages_helper.rb │ ├── tasks_helper.rb │ ├── turns_helper.rb │ ├── colonies_helper.rb │ ├── illnesses_helper.rb │ ├── locations_helper.rb │ ├── sufferings_helper.rb │ ├── application_helper.rb │ ├── assignments_helper.rb │ ├── task_user_wizard_helper.rb │ └── treatment_entries_helper.rb ├── jobs │ └── application_job.rb ├── channels │ └── application_cable │ │ ├── channel.rb │ │ └── connection.rb ├── mailers │ └── application_mailer.rb ├── validators │ ├── donation_validator.rb │ ├── treatment_entry_validator.rb │ ├── sponsor_validator.rb │ ├── turn_validator.rb │ ├── posession_validator.rb │ └── suffering_validator.rb └── policies │ ├── task_user_wizard_policy.rb │ ├── illness_policy.rb │ ├── turn_policy.rb │ ├── suffering_policy.rb │ ├── treatment_entry_policy.rb │ ├── cat_policy.rb │ └── application_policy.rb ├── .rspec ├── db ├── schema.png └── migrate │ ├── 20180523163003_add_colony_id_to_cats.rb │ ├── 20180821192912_add_saved_state_to_cats.rb │ ├── 20180523163043_add_location_id_to_colony.rb │ ├── 20180523162548_add_fk_to_treatment_entries.rb │ ├── 20181113205713_rename_birthay_field_in_cats.rb │ ├── 20181211220509_remove_location_table.rb │ ├── 20180523162055_add_fk_to_sufferings.rb │ ├── 20181208195116_add_dischargement_date_to_sufferings_table.rb │ ├── 20180516155412_create_colonies.rb │ ├── 20180516160028_create_tasks.rb │ ├── 20180516155947_create_assignments.rb │ ├── 20180523172628_create_turns_users.rb │ ├── 20180516160105_create_turns.rb │ ├── 20180516170016_create_adoptions.rb │ ├── 20180523145609_create_colonies_users.rb │ ├── 20180516162820_create_products.rb │ ├── 20180516165945_create_donations.rb │ ├── 20180516170345_create_posessions.rb │ ├── 20180516155337_create_treatment_entries.rb │ ├── 20180516155537_create_illnesses.rb │ ├── 20180516155229_create_sufferings.rb │ ├── 20180516154454_create_users.rb │ ├── 20180516155836_create_locations.rb │ ├── 20180516162547_create_sponsors.rb │ ├── 20180516162219_create_cats.rb │ └── 20180620160551_add_devise_to_users.rb ├── package.json ├── spec ├── support │ ├── factory_bot.rb │ └── bd.rb ├── models │ ├── adoption_spec.rb │ ├── turns_user_spec.rb │ ├── colonies_user_spec.rb │ ├── assignment_spec.rb │ ├── suffering_spec.rb │ ├── cat_spec.rb │ ├── posession_spec.rb │ ├── turn_spec.rb │ ├── donation_spec.rb │ ├── task_spec.rb │ ├── treatment_entry_spec.rb │ ├── illness_spec.rb │ ├── colony_spec.rb │ ├── sponsor_spec.rb │ ├── product_spec.rb │ └── user_spec.rb ├── validators │ ├── turn_validator_spec.rb │ ├── adoption_validator_spec.rb │ ├── donation_validator_spec.rb │ ├── posession_validator_spec.rb │ ├── sponsor_validator_spec.rb │ ├── treatment_entry_validator_spec.rb │ ├── cat_validator_spec.rb │ └── suffering_validator_spec.rb ├── factories.rb └── rails_helper.rb ├── bin ├── rake ├── bundle ├── rails ├── yarn ├── update └── setup ├── config ├── initializers │ ├── high_voltage.rb │ ├── mime_types.rb │ ├── filter_parameter_logging.rb │ ├── application_controller_renderer.rb │ ├── cookies_serializer.rb │ ├── backtrace_silencers.rb │ ├── wrap_parameters.rb │ ├── assets.rb │ └── inflections.rb ├── boot.rb ├── environment.rb ├── cable.yml ├── routes.rb ├── application.rb ├── locales │ └── en.yml ├── secrets.yml ├── environments │ ├── test.rb │ └── development.rb ├── favicon.json ├── puma.rb └── database.yml ├── config.ru ├── .idea ├── vcs.xml ├── misc.xml ├── modules.xml └── ConexionFelina.iml ├── Rakefile ├── .codeclimate.yml ├── .gitignore ├── .circleci └── config.yml ├── Gemfile └── README.md /log/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tmp/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /vendor/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/.nojekyll: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /lib/assets/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /lib/tasks/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/assets/images/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/models/concerns/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/apple-touch-icon.png: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/controllers/concerns/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/assets/javascripts/channels/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/apple-touch-icon-precomposed.png: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/views/layouts/mailer.text.erb: -------------------------------------------------------------------------------- 1 | <%= yield %> 2 | -------------------------------------------------------------------------------- /app/helpers/cats_helper.rb: -------------------------------------------------------------------------------- 1 | module CatsHelper 2 | end 3 | -------------------------------------------------------------------------------- /app/helpers/pages_helper.rb: -------------------------------------------------------------------------------- 1 | module PagesHelper 2 | end 3 | -------------------------------------------------------------------------------- /app/helpers/tasks_helper.rb: -------------------------------------------------------------------------------- 1 | module TasksHelper 2 | end 3 | -------------------------------------------------------------------------------- /app/helpers/turns_helper.rb: -------------------------------------------------------------------------------- 1 | module TurnsHelper 2 | end 3 | -------------------------------------------------------------------------------- /app/helpers/colonies_helper.rb: -------------------------------------------------------------------------------- 1 | module ColoniesHelper 2 | end 3 | -------------------------------------------------------------------------------- /app/helpers/illnesses_helper.rb: -------------------------------------------------------------------------------- 1 | module IllnessesHelper 2 | end 3 | -------------------------------------------------------------------------------- /app/helpers/locations_helper.rb: -------------------------------------------------------------------------------- 1 | module LocationsHelper 2 | end 3 | -------------------------------------------------------------------------------- /app/helpers/sufferings_helper.rb: -------------------------------------------------------------------------------- 1 | module SufferingsHelper 2 | end 3 | -------------------------------------------------------------------------------- /app/helpers/application_helper.rb: -------------------------------------------------------------------------------- 1 | module ApplicationHelper 2 | end 3 | -------------------------------------------------------------------------------- /app/helpers/assignments_helper.rb: -------------------------------------------------------------------------------- 1 | module AssignmentsHelper 2 | end 3 | -------------------------------------------------------------------------------- /.rspec: -------------------------------------------------------------------------------- 1 | --require spec_helper 2 | --color 3 | --format documentation 4 | 5 | -------------------------------------------------------------------------------- /app/helpers/task_user_wizard_helper.rb: -------------------------------------------------------------------------------- 1 | module TaskUserWizardHelper 2 | end 3 | -------------------------------------------------------------------------------- /app/jobs/application_job.rb: -------------------------------------------------------------------------------- 1 | class ApplicationJob < ActiveJob::Base 2 | end 3 | -------------------------------------------------------------------------------- /app/views/tasks/edit.html.erb: -------------------------------------------------------------------------------- 1 |

edit Task

2 | 3 | <%= render 'form' %> -------------------------------------------------------------------------------- /app/helpers/treatment_entries_helper.rb: -------------------------------------------------------------------------------- 1 | module TreatmentEntriesHelper 2 | end 3 | -------------------------------------------------------------------------------- /app/views/colonies/edit.html.erb: -------------------------------------------------------------------------------- 1 |

edit colony

2 | 3 | <%= render 'form' %> -------------------------------------------------------------------------------- /app/views/tasks/new.html.erb: -------------------------------------------------------------------------------- 1 |

Create a new Task

2 | 3 | <%= render 'form' %> -------------------------------------------------------------------------------- /db/schema.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/infusionvlc/ConexionFelina/HEAD/db/schema.png -------------------------------------------------------------------------------- /app/views/colonies/new.html.erb: -------------------------------------------------------------------------------- 1 |

Create a new colony

2 | 3 | <%= render 'form' %> -------------------------------------------------------------------------------- /public/capa.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/infusionvlc/ConexionFelina/HEAD/public/capa.gif -------------------------------------------------------------------------------- /public/dona.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/infusionvlc/ConexionFelina/HEAD/public/dona.gif -------------------------------------------------------------------------------- /public/dona.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/infusionvlc/ConexionFelina/HEAD/public/dona.png -------------------------------------------------------------------------------- /public/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/infusionvlc/ConexionFelina/HEAD/public/logo.png -------------------------------------------------------------------------------- /public/zen.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/infusionvlc/ConexionFelina/HEAD/public/zen.gif -------------------------------------------------------------------------------- /public/zen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/infusionvlc/ConexionFelina/HEAD/public/zen.png -------------------------------------------------------------------------------- /docs/assets/db.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/infusionvlc/ConexionFelina/HEAD/docs/assets/db.png -------------------------------------------------------------------------------- /public/Standar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/infusionvlc/ConexionFelina/HEAD/public/Standar.png -------------------------------------------------------------------------------- /public/adopta.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/infusionvlc/ConexionFelina/HEAD/public/adopta.gif -------------------------------------------------------------------------------- /public/adopta.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/infusionvlc/ConexionFelina/HEAD/public/adopta.png -------------------------------------------------------------------------------- /public/ciudad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/infusionvlc/ConexionFelina/HEAD/public/ciudad.png -------------------------------------------------------------------------------- /public/corazon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/infusionvlc/ConexionFelina/HEAD/public/corazon.png -------------------------------------------------------------------------------- /public/medalla.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/infusionvlc/ConexionFelina/HEAD/public/medalla.png -------------------------------------------------------------------------------- /public/plagas.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/infusionvlc/ConexionFelina/HEAD/public/plagas.png -------------------------------------------------------------------------------- /docs/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/infusionvlc/ConexionFelina/HEAD/docs/assets/logo.png -------------------------------------------------------------------------------- /docs/assets/zen.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/infusionvlc/ConexionFelina/HEAD/docs/assets/zen.gif -------------------------------------------------------------------------------- /public/adorables.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/infusionvlc/ConexionFelina/HEAD/public/adorables.gif -------------------------------------------------------------------------------- /public/adorables.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/infusionvlc/ConexionFelina/HEAD/public/adorables.png -------------------------------------------------------------------------------- /public/apadrina.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/infusionvlc/ConexionFelina/HEAD/public/apadrina.gif -------------------------------------------------------------------------------- /public/apadrina.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/infusionvlc/ConexionFelina/HEAD/public/apadrina.png -------------------------------------------------------------------------------- /public/explorar.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/infusionvlc/ConexionFelina/HEAD/public/explorar.gif -------------------------------------------------------------------------------- /public/explorar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/infusionvlc/ConexionFelina/HEAD/public/explorar.png -------------------------------------------------------------------------------- /public/instagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/infusionvlc/ConexionFelina/HEAD/public/instagram.png -------------------------------------------------------------------------------- /public/seguridad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/infusionvlc/ConexionFelina/HEAD/public/seguridad.png -------------------------------------------------------------------------------- /public/sociable.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/infusionvlc/ConexionFelina/HEAD/public/sociable.png -------------------------------------------------------------------------------- /docs/assets/colors.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/infusionvlc/ConexionFelina/HEAD/docs/assets/colors.png -------------------------------------------------------------------------------- /docs/assets/heroe.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/infusionvlc/ConexionFelina/HEAD/docs/assets/heroe.gif -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "conexion_felina", 3 | "private": true, 4 | "dependencies": {} 5 | } 6 | -------------------------------------------------------------------------------- /public/street_cat.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/infusionvlc/ConexionFelina/HEAD/public/street_cat.jpg -------------------------------------------------------------------------------- /docs/assets/ui_sample.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/infusionvlc/ConexionFelina/HEAD/docs/assets/ui_sample.PNG -------------------------------------------------------------------------------- /spec/support/factory_bot.rb: -------------------------------------------------------------------------------- 1 | RSpec.configure do |config| 2 | config.include FactoryBot::Syntax::Methods 3 | end -------------------------------------------------------------------------------- /app/models/turns_user.rb: -------------------------------------------------------------------------------- 1 | class TurnsUser < ApplicationRecord 2 | belongs_to :user 3 | belongs_to :turn 4 | end 5 | -------------------------------------------------------------------------------- /app/views/colonies/destroy.html.erb: -------------------------------------------------------------------------------- 1 |

Colonies#destroy

2 |

Find me in app/views/colonies/destroy.html.erb

-------------------------------------------------------------------------------- /bin/rake: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby.exe 2 | require_relative '../config/boot' 3 | require 'rake' 4 | Rake.application.run 5 | -------------------------------------------------------------------------------- /docs/assets/street_cat.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/infusionvlc/ConexionFelina/HEAD/docs/assets/street_cat.jpg -------------------------------------------------------------------------------- /app/models/application_record.rb: -------------------------------------------------------------------------------- 1 | class ApplicationRecord < ActiveRecord::Base 2 | self.abstract_class = true 3 | end 4 | -------------------------------------------------------------------------------- /app/views/illnesses/create.html.erb: -------------------------------------------------------------------------------- 1 |

Illnesses#create

2 |

Find me in app/views/illnesses/create.html.erb

3 | -------------------------------------------------------------------------------- /app/views/illnesses/update.html.erb: -------------------------------------------------------------------------------- 1 |

Illnesses#update

2 |

Find me in app/views/illnesses/update.html.erb

3 | -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | # See http://www.robotstxt.org/robotstxt.html for documentation on how to use the robots.txt file 2 | -------------------------------------------------------------------------------- /app/models/colonies_user.rb: -------------------------------------------------------------------------------- 1 | class ColoniesUser < ApplicationRecord 2 | belongs_to :colony 3 | belongs_to :user 4 | end 5 | -------------------------------------------------------------------------------- /app/views/illnesses/destroy.html.erb: -------------------------------------------------------------------------------- 1 |

Illnesses#destroy

2 |

Find me in app/views/illnesses/destroy.html.erb

3 | -------------------------------------------------------------------------------- /app/views/locations/destroy.html.erb: -------------------------------------------------------------------------------- 1 |

Locations#destroy

2 |

Find me in app/views/locations/destroy.html.erb

3 | -------------------------------------------------------------------------------- /app/channels/application_cable/channel.rb: -------------------------------------------------------------------------------- 1 | module ApplicationCable 2 | class Channel < ActionCable::Channel::Base 3 | end 4 | end 5 | -------------------------------------------------------------------------------- /app/views/cats/adopt.html.erb: -------------------------------------------------------------------------------- 1 | ¡Muchas gracias por tu interés en <%= @cat.name %>! Muy pronto nos pondremos en contacto contigo por e-mail. -------------------------------------------------------------------------------- /config/initializers/high_voltage.rb: -------------------------------------------------------------------------------- 1 | HighVoltage.configure do |config| 2 | config.route_drawer = HighVoltage::RouteDrawers::Root 3 | end -------------------------------------------------------------------------------- /app/assets/config/manifest.js: -------------------------------------------------------------------------------- 1 | //= link_tree ../images 2 | //= link_directory ../javascripts .js 3 | //= link_directory ../stylesheets .css 4 | -------------------------------------------------------------------------------- /app/channels/application_cable/connection.rb: -------------------------------------------------------------------------------- 1 | module ApplicationCable 2 | class Connection < ActionCable::Connection::Base 3 | end 4 | end 5 | -------------------------------------------------------------------------------- /app/models/assignment.rb: -------------------------------------------------------------------------------- 1 | class Assignment < ApplicationRecord 2 | belongs_to :colony 3 | belongs_to :task 4 | 5 | has_many :turns 6 | end 7 | -------------------------------------------------------------------------------- /app/mailers/application_mailer.rb: -------------------------------------------------------------------------------- 1 | class ApplicationMailer < ActionMailer::Base 2 | default from: 'from@example.com' 3 | layout 'mailer' 4 | end 5 | -------------------------------------------------------------------------------- /bin/bundle: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby.exe 2 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__) 3 | load Gem.bin_path('bundler', 'bundle') 4 | -------------------------------------------------------------------------------- /config/boot.rb: -------------------------------------------------------------------------------- 1 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__) 2 | 3 | require 'bundler/setup' # Set up gems listed in the Gemfile. 4 | -------------------------------------------------------------------------------- /config.ru: -------------------------------------------------------------------------------- 1 | # This file is used by Rack-based servers to start the application. 2 | 3 | require_relative 'config/environment' 4 | 5 | run Rails.application 6 | -------------------------------------------------------------------------------- /bin/rails: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby.exe 2 | APP_PATH = File.expand_path('../config/application', __dir__) 3 | require_relative '../config/boot' 4 | require 'rails/commands' 5 | -------------------------------------------------------------------------------- /config/environment.rb: -------------------------------------------------------------------------------- 1 | # Load the Rails application. 2 | require_relative 'application' 3 | 4 | # Initialize the Rails application. 5 | Rails.application.initialize! 6 | -------------------------------------------------------------------------------- /app/models/adoption.rb: -------------------------------------------------------------------------------- 1 | class Adoption < ApplicationRecord 2 | belongs_to :cat 3 | belongs_to :user 4 | 5 | validates :date, presence: true, on: :update 6 | 7 | end 8 | -------------------------------------------------------------------------------- /app/views/devise/mailer/password_change.html.erb: -------------------------------------------------------------------------------- 1 |

Hello <%= @resource.email %>!

2 | 3 |

We're contacting you to notify you that your password has been changed.

4 | -------------------------------------------------------------------------------- /spec/models/adoption_spec.rb: -------------------------------------------------------------------------------- 1 | require 'rails_helper' 2 | 3 | RSpec.describe Adoption, type: :model do 4 | it { should belong_to :cat } 5 | it { should belong_to :user } 6 | end 7 | -------------------------------------------------------------------------------- /spec/models/turns_user_spec.rb: -------------------------------------------------------------------------------- 1 | require 'rails_helper' 2 | 3 | RSpec.describe TurnsUser, type: :model do 4 | it { should belong_to :turn } 5 | it { should belong_to :user } 6 | end 7 | -------------------------------------------------------------------------------- /db/migrate/20180523163003_add_colony_id_to_cats.rb: -------------------------------------------------------------------------------- 1 | class AddColonyIdToCats < ActiveRecord::Migration[5.1] 2 | def change 3 | add_column :cats, :colony_id, :integer 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /db/migrate/20180821192912_add_saved_state_to_cats.rb: -------------------------------------------------------------------------------- 1 | class AddSavedStateToCats < ActiveRecord::Migration[5.1] 2 | def change 3 | add_column :cats, :saved_state, :string 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /spec/models/colonies_user_spec.rb: -------------------------------------------------------------------------------- 1 | require 'rails_helper' 2 | 3 | RSpec.describe ColoniesUser, type: :model do 4 | it { should belong_to :user } 5 | it { should belong_to :colony } 6 | end 7 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /app/models/posession.rb: -------------------------------------------------------------------------------- 1 | class Posession < ApplicationRecord 2 | belongs_to :product 3 | belongs_to :user 4 | 5 | validates :date, presence: true 6 | validates_with PosessionValidator 7 | end 8 | -------------------------------------------------------------------------------- /config/initializers/mime_types.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new mime types for use in respond_to blocks: 4 | # Mime::Type.register "text/richtext", :rtf 5 | -------------------------------------------------------------------------------- /db/migrate/20180523163043_add_location_id_to_colony.rb: -------------------------------------------------------------------------------- 1 | class AddLocationIdToColony < ActiveRecord::Migration[5.1] 2 | def change 3 | add_column :colonies, :location_id, :integer 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /app/assets/stylesheets/cats.scss: -------------------------------------------------------------------------------- 1 | // Place all the styles related to the cats controller here. 2 | // They will automatically be included in application.css. 3 | // You can use Sass (SCSS) here: http://sass-lang.com/ 4 | -------------------------------------------------------------------------------- /app/assets/stylesheets/turns.scss: -------------------------------------------------------------------------------- 1 | // Place all the styles related to the turns controller here. 2 | // They will automatically be included in application.css. 3 | // You can use Sass (SCSS) here: http://sass-lang.com/ 4 | -------------------------------------------------------------------------------- /app/views/tasks/show.html.erb: -------------------------------------------------------------------------------- 1 |

<%= @task.name %>

2 |

<%= @task.description %>

3 | 4 | <%= link_to "edit", edit_task_path(@task.id) %>
5 | <%= link_to "destroy", task_path(@task.id), method: :delete %> -------------------------------------------------------------------------------- /db/migrate/20180523162548_add_fk_to_treatment_entries.rb: -------------------------------------------------------------------------------- 1 | class AddFkToTreatmentEntries < ActiveRecord::Migration[5.1] 2 | def change 3 | add_column :treatment_entries, :suffering_id, :integer 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /db/migrate/20181113205713_rename_birthay_field_in_cats.rb: -------------------------------------------------------------------------------- 1 | class RenameBirthayFieldInCats < ActiveRecord::Migration[5.1] 2 | def change 3 | rename_column :cats, :birthdate_date, :birthday_date 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /app/assets/stylesheets/pages.scss: -------------------------------------------------------------------------------- 1 | // Place all the styles related to the pages controller here. 2 | // They will automatically be included in application.css. 3 | // You can use Sass (SCSS) here: http://sass-lang.com/ 4 | 5 | -------------------------------------------------------------------------------- /config/cable.yml: -------------------------------------------------------------------------------- 1 | development: 2 | adapter: async 3 | 4 | test: 5 | adapter: async 6 | 7 | production: 8 | adapter: redis 9 | url: redis://localhost:6379/1 10 | channel_prefix: conexion_felina_production 11 | -------------------------------------------------------------------------------- /spec/models/assignment_spec.rb: -------------------------------------------------------------------------------- 1 | require 'rails_helper' 2 | 3 | RSpec.describe Assignment, type: :model do 4 | it { should belong_to :task } 5 | it { should belong_to :colony } 6 | it { should have_many :turns } 7 | end 8 | -------------------------------------------------------------------------------- /app/assets/stylesheets/illnesses.scss: -------------------------------------------------------------------------------- 1 | // Place all the styles related to the illnesses controller here. 2 | // They will automatically be included in application.css. 3 | // You can use Sass (SCSS) here: http://sass-lang.com/ 4 | -------------------------------------------------------------------------------- /app/assets/stylesheets/locations.scss: -------------------------------------------------------------------------------- 1 | // Place all the styles related to the locations controller here. 2 | // They will automatically be included in application.css. 3 | // You can use Sass (SCSS) here: http://sass-lang.com/ 4 | -------------------------------------------------------------------------------- /app/assets/stylesheets/sufferings.scss: -------------------------------------------------------------------------------- 1 | // Place all the styles related to the sufferings controller here. 2 | // They will automatically be included in application.css. 3 | // You can use Sass (SCSS) here: http://sass-lang.com/ 4 | -------------------------------------------------------------------------------- /app/views/illnesses/index.html.erb: -------------------------------------------------------------------------------- 1 |

Illnesses

2 | 3 | <%= link_to "create", new_illness_path %>
4 | 5 | <% @illnesses.each do | illness | %> 6 | <%= link_to illness.name, illness_path( illness.id ) %>
7 | <% end %> -------------------------------------------------------------------------------- /db/migrate/20181211220509_remove_location_table.rb: -------------------------------------------------------------------------------- 1 | class RemoveLocationTable < ActiveRecord::Migration[5.2] 2 | def change 3 | add_column :colonies, :location, :string 4 | drop_table :locations 5 | end 6 | 7 | 8 | end 9 | -------------------------------------------------------------------------------- /app/assets/stylesheets/task_user_wizard.scss: -------------------------------------------------------------------------------- 1 | // Place all the styles related to the task_user_wizard controller here. 2 | // They will automatically be included in application.css. 3 | // You can use Sass (SCSS) here: http://sass-lang.com/ 4 | -------------------------------------------------------------------------------- /app/assets/stylesheets/treatment_entries.scss: -------------------------------------------------------------------------------- 1 | // Place all the styles related to the treatment_entry controller here. 2 | // They will automatically be included in application.css. 3 | // You can use Sass (SCSS) here: http://sass-lang.com/ 4 | -------------------------------------------------------------------------------- /app/controllers/pages_controller.rb: -------------------------------------------------------------------------------- 1 | class PagesController < ApplicationController 2 | def home; end 3 | 4 | def collaborate; end 5 | 6 | def about; end 7 | 8 | def principles; end 9 | 10 | def league; end 11 | end 12 | -------------------------------------------------------------------------------- /db/migrate/20180523162055_add_fk_to_sufferings.rb: -------------------------------------------------------------------------------- 1 | class AddFkToSufferings < ActiveRecord::Migration[5.1] 2 | def change 3 | add_column :sufferings, :cat_id, :integer 4 | add_column :sufferings, :illness_id, :integer 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /db/migrate/20181208195116_add_dischargement_date_to_sufferings_table.rb: -------------------------------------------------------------------------------- 1 | class AddDischargementDateToSufferingsTable < ActiveRecord::Migration[5.2] 2 | def change 3 | add_column :sufferings, :dischargement_date, :datetime 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /app/models/turn.rb: -------------------------------------------------------------------------------- 1 | class Turn < ApplicationRecord 2 | validates :start_date, presence: true 3 | validates :end_date, presence: true 4 | validates_with TurnValidator 5 | 6 | belongs_to :assignment 7 | has_and_belongs_to_many :users 8 | end 9 | -------------------------------------------------------------------------------- /spec/models/suffering_spec.rb: -------------------------------------------------------------------------------- 1 | require 'rails_helper' 2 | 3 | RSpec.describe Suffering, type: :model do 4 | 5 | it {should have_many :treatment_entries} 6 | it {should belong_to :cat} 7 | it {should belong_to :illness} 8 | 9 | end 10 | -------------------------------------------------------------------------------- /app/assets/javascripts/cats.coffee: -------------------------------------------------------------------------------- 1 | # Place all the behaviors and hooks related to the matching controller here. 2 | # All this logic will automatically be available in application.js. 3 | # You can use CoffeeScript in this file: http://coffeescript.org/ 4 | -------------------------------------------------------------------------------- /app/assets/javascripts/pages.coffee: -------------------------------------------------------------------------------- 1 | # Place all the behaviors and hooks related to the matching controller here. 2 | # All this logic will automatically be available in application.js. 3 | # You can use CoffeeScript in this file: http://coffeescript.org/ 4 | -------------------------------------------------------------------------------- /app/assets/javascripts/turns.coffee: -------------------------------------------------------------------------------- 1 | # Place all the behaviors and hooks related to the matching controller here. 2 | # All this logic will automatically be available in application.js. 3 | # You can use CoffeeScript in this file: http://coffeescript.org/ 4 | -------------------------------------------------------------------------------- /app/views/colonies/index.html.erb: -------------------------------------------------------------------------------- 1 |

Colonies

2 | 3 | <%= link_to "create", new_colony_path %>
4 | 5 | <% @colonies.each do | colony | %> 6 | <%= link_to colony.name, colony_path( colony.id ) %>
7 | <%= colony.bio %>
8 | <% end %> -------------------------------------------------------------------------------- /config/initializers/filter_parameter_logging.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Configure sensitive parameters which will be filtered from the log file. 4 | Rails.application.config.filter_parameters += [:password] 5 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | # Add your own tasks in files placed in lib/tasks ending in .rake, 2 | # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. 3 | 4 | require_relative 'config/application' 5 | 6 | Rails.application.load_tasks 7 | -------------------------------------------------------------------------------- /app/assets/javascripts/illnesses.coffee: -------------------------------------------------------------------------------- 1 | # Place all the behaviors and hooks related to the matching controller here. 2 | # All this logic will automatically be available in application.js. 3 | # You can use CoffeeScript in this file: http://coffeescript.org/ 4 | -------------------------------------------------------------------------------- /app/assets/javascripts/locations.coffee: -------------------------------------------------------------------------------- 1 | # Place all the behaviors and hooks related to the matching controller here. 2 | # All this logic will automatically be available in application.js. 3 | # You can use CoffeeScript in this file: http://coffeescript.org/ 4 | -------------------------------------------------------------------------------- /app/assets/javascripts/sufferings.coffee: -------------------------------------------------------------------------------- 1 | # Place all the behaviors and hooks related to the matching controller here. 2 | # All this logic will automatically be available in application.js. 3 | # You can use CoffeeScript in this file: http://coffeescript.org/ 4 | -------------------------------------------------------------------------------- /spec/models/cat_spec.rb: -------------------------------------------------------------------------------- 1 | require 'rails_helper' 2 | 3 | RSpec.describe Cat, type: :model do 4 | it { should have_many :sufferings} 5 | it { should belong_to :colony } 6 | it { should have_one :adoption } 7 | it { should have_many :sponsors } 8 | end 9 | -------------------------------------------------------------------------------- /app/assets/javascripts/task_user_wizard.coffee: -------------------------------------------------------------------------------- 1 | # Place all the behaviors and hooks related to the matching controller here. 2 | # All this logic will automatically be available in application.js. 3 | # You can use CoffeeScript in this file: http://coffeescript.org/ 4 | -------------------------------------------------------------------------------- /app/assets/javascripts/treatment_entries.coffee: -------------------------------------------------------------------------------- 1 | # Place all the behaviors and hooks related to the matching controller here. 2 | # All this logic will automatically be available in application.js. 3 | # You can use CoffeeScript in this file: http://coffeescript.org/ 4 | -------------------------------------------------------------------------------- /db/migrate/20180516155412_create_colonies.rb: -------------------------------------------------------------------------------- 1 | class CreateColonies < ActiveRecord::Migration[5.1] 2 | def change 3 | create_table :colonies do |t| 4 | t.string :name 5 | t.text :bio 6 | 7 | t.timestamps 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /db/migrate/20180516160028_create_tasks.rb: -------------------------------------------------------------------------------- 1 | class CreateTasks < ActiveRecord::Migration[5.1] 2 | def change 3 | create_table :tasks do |t| 4 | t.string :name 5 | t.text :description 6 | 7 | t.timestamps 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /docs/_coverpage.md: -------------------------------------------------------------------------------- 1 | ![logo](assets/logo.svg) 2 | 3 | # covi project 4 | 5 | > A web application for managing cat colonies. 6 | 7 | [GitHub](https://github.com/infusionvlc/ConexionFelina) 8 | [Get Started](#covi-project) 9 | 10 | ![](assets/street_cat.jpg) 11 | -------------------------------------------------------------------------------- /app/views/cats/build/add_origin.html.erb: -------------------------------------------------------------------------------- 1 |

Colonia o abandono

2 |
3 | <%= link_to 'colony', wizard_path(:add_colony) %> 4 |
5 |
6 | <%= link_to 'abandoned', wizard_path(:add_abandoned_date) %> 7 |
8 |
9 | -------------------------------------------------------------------------------- /app/views/cats/build/has_been_to_vet.html.erb: -------------------------------------------------------------------------------- 1 |

¿Ha ido al veterinario alguna vez?

2 |
3 | <%= link_to 'sí', wizard_path(:add_vet_info) %> 4 |
5 |
6 | <%= link_to 'no', wizard_path(:add_bio) %> 7 |
8 |
9 | -------------------------------------------------------------------------------- /app/views/devise/mailer/confirmation_instructions.html.erb: -------------------------------------------------------------------------------- 1 |

Welcome <%= @email %>!

2 | 3 |

You can confirm your account email through the link below:

4 | 5 |

<%= link_to 'Confirm my account', confirmation_url(@resource, confirmation_token: @token) %>

6 | -------------------------------------------------------------------------------- /app/views/locations/index.html.erb: -------------------------------------------------------------------------------- 1 |

Locations

2 | 3 | <%= link_to "create", new_location_path %>
4 | 5 | <% @locations.each do | location | %> 6 | <%= link_to location.name, location_path( location.id ) %>
7 | <%= location.description %>
8 | <% end %> -------------------------------------------------------------------------------- /app/views/locations/show.html.erb: -------------------------------------------------------------------------------- 1 |

<%= @location.name %>

2 |

<%= @location.description %>

3 |

<%= @location.address %>

4 | 5 | <%= link_to "edit", edit_location_path(@location.id) %>
6 | <%= link_to "destroy", location_path(@location.id), method: :delete %> -------------------------------------------------------------------------------- /db/migrate/20180516155947_create_assignments.rb: -------------------------------------------------------------------------------- 1 | class CreateAssignments < ActiveRecord::Migration[5.1] 2 | def change 3 | create_table :assignments do |t| 4 | t.integer :colony_id 5 | t.integer :task_id 6 | t.timestamps 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /db/migrate/20180523172628_create_turns_users.rb: -------------------------------------------------------------------------------- 1 | class CreateTurnsUsers < ActiveRecord::Migration[5.1] 2 | def change 3 | create_table :turns_users do |t| 4 | t.integer :user_id 5 | t.integer :turn_id 6 | 7 | t.timestamps 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /app/views/tasks/_form.html.erb: -------------------------------------------------------------------------------- 1 | <%= form_for (@task) do |f| %> 2 | 3 | <%= f.label :name %>
4 | <%= f.text_field :name %>

5 | 6 | <%= f.label :description %>
7 | <%= f.text_area :description %>

8 | 9 | <%= f.submit %> 10 | <% end %> -------------------------------------------------------------------------------- /spec/models/posession_spec.rb: -------------------------------------------------------------------------------- 1 | require 'rails_helper' 2 | 3 | RSpec.describe Posession, type: :model do 4 | it { should belong_to :user } 5 | it { should belong_to :product } 6 | 7 | context 'validations' do 8 | it { should validate_presence_of(:date) } 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /config/initializers/application_controller_renderer.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # ActiveSupport::Reloader.to_prepare do 4 | # ApplicationController.renderer.defaults.merge!( 5 | # http_host: 'example.org', 6 | # https: false 7 | # ) 8 | # end 9 | -------------------------------------------------------------------------------- /db/migrate/20180516160105_create_turns.rb: -------------------------------------------------------------------------------- 1 | class CreateTurns < ActiveRecord::Migration[5.1] 2 | def change 3 | create_table :turns do |t| 4 | t.date :start_date 5 | t.date :end_date 6 | t.integer :assignment_id 7 | t.timestamps 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /db/migrate/20180516170016_create_adoptions.rb: -------------------------------------------------------------------------------- 1 | class CreateAdoptions < ActiveRecord::Migration[5.1] 2 | def change 3 | create_table :adoptions do |t| 4 | t.date :date 5 | t.integer :user_id 6 | t.integer :cat_id 7 | t.timestamps 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /db/migrate/20180523145609_create_colonies_users.rb: -------------------------------------------------------------------------------- 1 | class CreateColoniesUsers < ActiveRecord::Migration[5.1] 2 | def change 3 | create_table :colonies_users do |t| 4 | t.integer :user_id 5 | t.integer :colony_id 6 | 7 | t.timestamps 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /config/initializers/cookies_serializer.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Specify a serializer for the signed and encrypted cookie jars. 4 | # Valid options are :json, :marshal, and :hybrid. 5 | Rails.application.config.action_dispatch.cookies_serializer = :json 6 | -------------------------------------------------------------------------------- /db/migrate/20180516162820_create_products.rb: -------------------------------------------------------------------------------- 1 | class CreateProducts < ActiveRecord::Migration[5.1] 2 | def change 3 | create_table :products do |t| 4 | t.string :name 5 | t.integer :stock 6 | t.integer :price 7 | 8 | t.timestamps 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /db/migrate/20180516165945_create_donations.rb: -------------------------------------------------------------------------------- 1 | class CreateDonations < ActiveRecord::Migration[5.1] 2 | def change 3 | create_table :donations do |t| 4 | t.integer :amount 5 | t.date :date 6 | t.integer :user_id 7 | 8 | t.timestamps 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /app/validators/donation_validator.rb: -------------------------------------------------------------------------------- 1 | class DonationValidator < ActiveModel::Validator 2 | MINIMUM_AMOUNT_VALUE = 0 3 | 4 | def validate(record) 5 | if !record.date.nil? && record.date > Date.today 6 | record.errors[:date] << "Date must be in the past" 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /app/views/illnesses/show.html.erb: -------------------------------------------------------------------------------- 1 |

<%= @illness.name %>

2 |

<%= @illness.description %>

3 |

<%= @illness.priority %>

4 |

<%= @illness.treatment %>

5 | 6 | <%= link_to "edit", edit_illness_path(@illness.id) %>
7 | <%= link_to "destroy", illness_path(@illness.id), method: :delete %> -------------------------------------------------------------------------------- /db/migrate/20180516170345_create_posessions.rb: -------------------------------------------------------------------------------- 1 | class CreatePosessions < ActiveRecord::Migration[5.1] 2 | def change 3 | create_table :posessions do |t| 4 | t.date :date 5 | t.integer :user_id 6 | t.integer :product_id 7 | 8 | t.timestamps 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /app/validators/treatment_entry_validator.rb: -------------------------------------------------------------------------------- 1 | class TreatmentEntryValidator < ActiveModel::Validator 2 | MAXIMUM_CHARACTERS = 1024 3 | 4 | def validate(record) 5 | if !record.date.nil? && record.date > Date.today 6 | record.errors[:date] << " date must be in the past" 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /app/views/layouts/mailer.html.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 8 | 9 | 10 | 11 | <%= yield %> 12 | 13 | 14 | -------------------------------------------------------------------------------- /app/models/donation.rb: -------------------------------------------------------------------------------- 1 | class Donation < ApplicationRecord 2 | MINIMUM_AMOUNT_VALUE = 0 3 | 4 | belongs_to :user 5 | 6 | validates :amount, :date, presence: true 7 | validates :amount, numericality: {only_integer: true, greater_than: MINIMUM_AMOUNT_VALUE} 8 | 9 | validates_with DonationValidator 10 | end 11 | -------------------------------------------------------------------------------- /db/migrate/20180516155337_create_treatment_entries.rb: -------------------------------------------------------------------------------- 1 | class CreateTreatmentEntries < ActiveRecord::Migration[5.1] 2 | def change 3 | create_table :treatment_entries do |t| 4 | t.date :date 5 | t.integer :treatment 6 | t.text :notes 7 | 8 | t.timestamps 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /app/models/suffering.rb: -------------------------------------------------------------------------------- 1 | class Suffering < ApplicationRecord 2 | enum statuses: [:initial, :mild, :advanced, :stable, :healthy] 3 | 4 | has_many :treatment_entries 5 | belongs_to :cat 6 | belongs_to :illness 7 | 8 | validates :status, inclusion: { in: statuses.values } 9 | validates_with SufferingValidator 10 | end 11 | -------------------------------------------------------------------------------- /db/migrate/20180516155537_create_illnesses.rb: -------------------------------------------------------------------------------- 1 | class CreateIllnesses < ActiveRecord::Migration[5.1] 2 | def change 3 | create_table :illnesses do |t| 4 | t.string :name 5 | t.text :description 6 | t.integer :priority 7 | t.text :treatment 8 | 9 | t.timestamps 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /db/migrate/20180516155229_create_sufferings.rb: -------------------------------------------------------------------------------- 1 | class CreateSufferings < ActiveRecord::Migration[5.1] 2 | def change 3 | create_table :sufferings do |t| 4 | t.date :diagnosis_date 5 | t.text :notes 6 | t.boolean :chronic 7 | t.integer :status 8 | 9 | t.timestamps 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /db/migrate/20180516154454_create_users.rb: -------------------------------------------------------------------------------- 1 | class CreateUsers < ActiveRecord::Migration[5.1] 2 | def change 3 | create_table :users do |t| 4 | t.string :username 5 | t.integer :role 6 | t.text :bio 7 | t.string :avatar 8 | t.integer :purrs 9 | 10 | t.timestamps 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /app/views/devise/mailer/unlock_instructions.html.erb: -------------------------------------------------------------------------------- 1 |

Hello <%= @resource.email %>!

2 | 3 |

Your account has been locked due to an excessive number of unsuccessful sign in attempts.

4 | 5 |

Click the link below to unlock your account:

6 | 7 |

<%= link_to 'Unlock my account', unlock_url(@resource, unlock_token: @token) %>

8 | -------------------------------------------------------------------------------- /app/validators/sponsor_validator.rb: -------------------------------------------------------------------------------- 1 | class SponsorValidator < ActiveModel::Validator 2 | MINIMUM_AMOUNT_VALUE = 0 3 | 4 | def validate(record) 5 | if !record.last_payment_date.nil? && record.last_payment_date > Date.today 6 | record.errors[:last_payment_date] << "Last payment date must be in the past" 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /app/views/cats/build/add_bio.html.erb: -------------------------------------------------------------------------------- 1 |

Cuéntanos más

2 | <%= form_for(@cat, :url => wizard_path, :method => :put) do |f| %> 3 |
4 | <%= f.label :bio %>
5 | <%= f.text_area :bio, class: 'form-control' %> 6 |
7 |
8 | <%= f.submit 'Siguiente', :class => 'btn btn-primary' %> 9 | <% end %> 10 | -------------------------------------------------------------------------------- /app/views/cats/build/finish.html.erb: -------------------------------------------------------------------------------- 1 |

Muchas gracias. ¿Qué quieres hacer ahora?

2 | 3 | <%= form_for(@cat, :url => wizard_path, :method => :put) do |f| %> 4 | <%= f.hidden_field :saved_state, value: 'active' %> 5 | <%= f.submit "profile", :class => 'btn btn-primary' %> 6 | <%= f.submit "repeat", :class => 'btn btn-primary' %> 7 | <% end %> 8 | -------------------------------------------------------------------------------- /app/views/tasks/index.html.erb: -------------------------------------------------------------------------------- 1 |

Tasks

2 | 3 | <%= link_to "create", new_task_path %>

4 | 5 | <% @tasks.each do | task | %> 6 | <%= link_to task.name, task_path( task.id ) %>
7 | <%= task.description %> 8 | <%= link_to "Assign this task to a user", new_task_user_wizard_path(task_id: task.id) %>
9 |
10 | <% end %> -------------------------------------------------------------------------------- /spec/models/turn_spec.rb: -------------------------------------------------------------------------------- 1 | require 'rails_helper' 2 | 3 | RSpec.describe Turn, type: :model do 4 | context 'validations' do 5 | it { should validate_presence_of(:start_date) } 6 | it { should validate_presence_of(:end_date) } 7 | end 8 | 9 | it { should belong_to :assignment } 10 | it { should have_and_belong_to_many :users } 11 | end 12 | -------------------------------------------------------------------------------- /bin/yarn: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby.exe 2 | VENDOR_PATH = File.expand_path('..', __dir__) 3 | Dir.chdir(VENDOR_PATH) do 4 | begin 5 | exec "yarnpkg #{ARGV.join(' ')}" 6 | rescue Errno::ENOENT 7 | warn 'Yarn executable was not detected in the system.' 8 | warn 'Download Yarn at https://yarnpkg.com/en/docs/install' 9 | exit 1 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /app/views/assignments/new.html.erb: -------------------------------------------------------------------------------- 1 |

Create a new Assignment

2 | 3 | <%= form_for (@assignment) do |f| %> 4 | 5 | <%= f.hidden_field :colony_id %>

6 | 7 | <%= f.label :task_id %>
8 | <%= f.select(:task_id, Task.all.collect {|u| [u.name, u.id]}, :prompt => 'Select') %>

9 | 10 | <%= f.submit %> 11 | <% end %> -------------------------------------------------------------------------------- /db/migrate/20180516155836_create_locations.rb: -------------------------------------------------------------------------------- 1 | class CreateLocations < ActiveRecord::Migration[5.1] 2 | def change 3 | create_table :locations do |t| 4 | t.string :name 5 | t.text :description 6 | t.decimal :longitude 7 | t.decimal :latitude 8 | t.string :address 9 | 10 | t.timestamps 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /app/views/colonies/_form.html.erb: -------------------------------------------------------------------------------- 1 | <%= form_for (@colony) do |f| %> 2 | 3 | <%= f.label :name %>
4 | <%= f.text_field :name %>

5 | 6 | <%= f.label :bio %>
7 | <%= f.text_area :bio %>

8 | 9 | <%= f.label :location %>
10 | <%= f.text_field :location%>

11 | 12 | <%= f.submit %> 13 | <% end %> 14 | -------------------------------------------------------------------------------- /app/views/devise/mailer/email_changed.html.erb: -------------------------------------------------------------------------------- 1 |

Hello <%= @email %>!

2 | 3 | <% if @resource.try(:unconfirmed_email?) %> 4 |

We're contacting you to notify you that your email is being changed to <%= @resource.unconfirmed_email %>.

5 | <% else %> 6 |

We're contacting you to notify you that your email has been changed to <%= @resource.email %>.

7 | <% end %> 8 | -------------------------------------------------------------------------------- /app/models/task.rb: -------------------------------------------------------------------------------- 1 | class Task < ApplicationRecord 2 | MAXIMUM_NAME_LENGTH = 50 3 | MAXIMUM_BIO_LENGTH = 1024 4 | 5 | has_many :assignments 6 | has_many :colonies, through: :assignments 7 | 8 | validates :name, presence: true 9 | validates :name, length: {maximum: MAXIMUM_NAME_LENGTH} 10 | validates :description, length: {maximum: MAXIMUM_BIO_LENGTH} 11 | end 12 | -------------------------------------------------------------------------------- /spec/models/donation_spec.rb: -------------------------------------------------------------------------------- 1 | require "rails_helper" 2 | 3 | RSpec.describe Donation, type: :model do 4 | 5 | it { should belong_to :user } 6 | 7 | context "validations" do 8 | it { should validate_presence_of(:amount) } 9 | it { should validate_numericality_of(:amount).is_greater_than 0 } 10 | it { should validate_presence_of(:date) } 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /app/views/cats/build/add_abandoned_date.html.erb: -------------------------------------------------------------------------------- 1 |

Sentimos mucho oír eso...

2 | <%= form_for(@cat, :url => wizard_path, :method => :put) do |f| %> 3 |
4 | <%= f.label :abandoned_date %>
5 | <%= f.date_field :abandoned_date, class: 'form-control' %> 6 |
7 |
8 | <%= f.submit 'Siguiente', :class => 'btn btn-primary' %> 9 | <% end %> 10 | -------------------------------------------------------------------------------- /db/migrate/20180516162547_create_sponsors.rb: -------------------------------------------------------------------------------- 1 | class CreateSponsors < ActiveRecord::Migration[5.1] 2 | def change 3 | create_table :sponsors do |t| 4 | t.date :start_date 5 | t.date :last_payment_date 6 | t.integer :amount 7 | t.boolean :renovate 8 | t.integer :user_id 9 | t.integer :cat_id 10 | 11 | t.timestamps 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /spec/models/task_spec.rb: -------------------------------------------------------------------------------- 1 | require "rails_helper" 2 | 3 | RSpec.describe Task, type: :model do 4 | MAXIMUM_NAME_LENGTH = 50 5 | MAXIMUM_BIO_LENGTH = 1024 6 | 7 | it { should have_many :assignments } 8 | 9 | context "validations" do 10 | it { should validate_presence_of(:name) } 11 | it { should validate_length_of(:name).is_at_most(MAXIMUM_NAME_LENGTH) } 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /app/models/product.rb: -------------------------------------------------------------------------------- 1 | class Product < ApplicationRecord 2 | MAXIMUM_NAME_LENGTH = 50 3 | MINIMUM_STOCK_PRICE_VALUE = 0 4 | 5 | has_many :posessions 6 | 7 | validates :name, :stock, :price, presence: true 8 | validates :name, length: {maximum: MAXIMUM_NAME_LENGTH} 9 | validates :stock, :price, numericality: {only_integer: true, greater_than_or_equal_to: MINIMUM_STOCK_PRICE_VALUE} 10 | end 11 | -------------------------------------------------------------------------------- /app/views/locations/edit.html.erb: -------------------------------------------------------------------------------- 1 |

edit location

2 | 3 | <%= form_for (@location) do |f| %> 4 | 5 | <%= f.label :name %>
6 | <%= f.text_field :name %>

7 | 8 | <%= f.label :description %>
9 | <%= f.text_area :description %>

10 | 11 | <%= f.label :address %>
12 | <%= f.text_field :address %>

13 | 14 | <%= f.submit %> 15 | <% end %> 16 | -------------------------------------------------------------------------------- /app/views/locations/new.html.erb: -------------------------------------------------------------------------------- 1 |

create a new location

2 | 3 | <%= form_for (@location) do |f| %> 4 | 5 | <%= f.label :name %>
6 | <%= f.text_field :name %>

7 | 8 | <%= f.label :description %>
9 | <%= f.text_area :description %>

10 | 11 | <%= f.label :address %>
12 | <%= f.text_field :address %>

13 | 14 | <%= f.submit %> 15 | <% end %> -------------------------------------------------------------------------------- /spec/support/bd.rb: -------------------------------------------------------------------------------- 1 | class ActiveRecord::Base 2 | mattr_accessor :shared_connection 3 | @@shared_connection = nil 4 | 5 | def self.connection 6 | @@shared_connection || retrieve_connection 7 | end 8 | end 9 | 10 | # Forces all threads to share the same connection. This works on 11 | # Capybara because it starts the web server in a thread. 12 | ActiveRecord::Base.shared_connection = ActiveRecord::Base.connection -------------------------------------------------------------------------------- /app/models/treatment_entry.rb: -------------------------------------------------------------------------------- 1 | class TreatmentEntry < ApplicationRecord 2 | MAXIMUM_CHARACTERS = 1024 3 | 4 | enum treatments: [:surgery, :diet, :medicine, :hospitalized, :hosted] 5 | 6 | belongs_to :suffering 7 | 8 | validates :date, presence: true 9 | validates :treatment, presence: true 10 | validates :notes, length: {maximum: MAXIMUM_CHARACTERS} 11 | 12 | validates_with TreatmentEntryValidator 13 | end 14 | -------------------------------------------------------------------------------- /app/validators/turn_validator.rb: -------------------------------------------------------------------------------- 1 | class TurnValidator < ActiveModel::Validator 2 | def validate(record) 3 | start_date = record.start_date 4 | end_date = record.end_date 5 | 6 | dates_exists = !start_date.nil? && !end_date.nil? 7 | 8 | if dates_exists && record.start_date > record.end_date 9 | record.errors[:start_date] << "End date must be later than the start date" 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /spec/models/treatment_entry_spec.rb: -------------------------------------------------------------------------------- 1 | require "rails_helper" 2 | 3 | RSpec.describe TreatmentEntry, type: :model do 4 | MAXIMUM_CHARACTERS = 1024 5 | 6 | it { should belong_to :suffering } 7 | context "validations" do 8 | it { should validate_presence_of :date } 9 | it { should validate_presence_of :treatment } 10 | it { should validate_length_of(:notes).is_at_most(MAXIMUM_CHARACTERS) } 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /app/controllers/application_controller.rb: -------------------------------------------------------------------------------- 1 | class ApplicationController < ActionController::Base 2 | include Pundit 3 | protect_from_forgery with: :exception 4 | 5 | before_action :configure_permitted_parameters, if: :devise_controller? 6 | 7 | protected 8 | 9 | def configure_permitted_parameters 10 | devise_parameter_sanitizer.permit(:sign_up, keys: [:username, :role, :bio, :avatar, :purrs]) 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /app/validators/posession_validator.rb: -------------------------------------------------------------------------------- 1 | class PosessionValidator < ActiveModel::Validator 2 | def validate(record) 3 | date = record.date 4 | 5 | if date.nil? 6 | record.errors[:date] << 'Possesion date is nil' 7 | end 8 | 9 | dates_exists = !date.nil? 10 | 11 | if dates_exists && record.date >= Date.today 12 | record.errors[:date] << 'Today must be later than the date' 13 | end 14 | end 15 | end -------------------------------------------------------------------------------- /app/views/cats/build/add_colony.erb: -------------------------------------------------------------------------------- 1 |

¿A qué colonia pertenece?

2 | <%= form_for(@cat, :url => wizard_path, :method => :put) do |f| %> 3 |
4 | <%= f.label :colony %>
5 | <%= f.select(:colony_id, Colony.all.collect {|u| [u.name, u.id]}, {:prompt => 'Select'}, {class: 'form-control'}) %>
6 |
7 |
8 | <%= f.submit 'Siguiente', :class => 'btn btn-primary' %> 9 | <% end %> 10 | -------------------------------------------------------------------------------- /db/migrate/20180516162219_create_cats.rb: -------------------------------------------------------------------------------- 1 | class CreateCats < ActiveRecord::Migration[5.1] 2 | def change 3 | create_table :cats do |t| 4 | t.string :name 5 | t.text :bio 6 | t.text :avatar 7 | t.date :birthdate_date 8 | t.integer :gender 9 | t.integer :sterilized 10 | t.date :abandoned_date 11 | t.string :document 12 | 13 | t.timestamps 14 | end 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /lib/tasks/cleanup.rake: -------------------------------------------------------------------------------- 1 | namespace :cleanup do 2 | desc 'removes stale and inactive cats from the database' 3 | task products: :environment do 4 | # Find all the cats older than yesterday, that are not active yet 5 | stale_cats = Cat.where('DATE(created_at) < DATE(?)', Date.yesterday) 6 | .where("status is not 'active'") 7 | 8 | # delete them 9 | stale_cats.map(&:destroy) 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /app/models/illness.rb: -------------------------------------------------------------------------------- 1 | class Illness < ApplicationRecord 2 | MAXIMUM_DESCRIPTION_LENGTH = 512 3 | 4 | enum priority: [ :low, :medium, :high ] 5 | 6 | has_many :sufferings 7 | has_many :cats, through: :sufferings 8 | 9 | validates :name, :description, :priority, :treatment, presence: true 10 | validates :name, length: {maximum: 20} 11 | validates :description, length: {maximum: MAXIMUM_DESCRIPTION_LENGTH} 12 | 13 | end 14 | -------------------------------------------------------------------------------- /app/views/turns/edit.html.erb: -------------------------------------------------------------------------------- 1 |

Turns#edit

2 | <%= form_for (@turn) do |f| %> 3 | 4 | <%= f.label :start_date %>
5 | <%= f.date_field :start_date %>

6 | 7 | <%= f.label :end_date %>
8 | <%= f.date_field :end_date %>

9 | 10 | <%= hidden_field_tag :assignment_id, params[:assignment_id] %> 11 | <%= hidden_field_tag :colony_id, params[:colony_id] %> 12 | 13 | <%= f.submit %> 14 | <% end %> -------------------------------------------------------------------------------- /app/views/turns/new.html.erb: -------------------------------------------------------------------------------- 1 |

Turns#new

2 | <%= form_for (@turn) do |f| %> 3 | 4 | <%= f.label :start_date %>
5 | <%= f.date_field :start_date %>

6 | 7 | <%= f.label :end_date %>
8 | <%= f.date_field :end_date %>

9 | 10 | <%= hidden_field_tag :assignment_id, params[:assignment_id] %> 11 | <%= hidden_field_tag :colony_id, params[:colony_id] %> 12 | 13 | <%= f.submit %> 14 | <% end %> -------------------------------------------------------------------------------- /app/assets/javascripts/cable.js: -------------------------------------------------------------------------------- 1 | // Action Cable provides the framework to deal with WebSockets in Rails. 2 | // You can generate new channels where WebSocket features live using the `rails generate channel` command. 3 | // 4 | //= require action_cable 5 | //= require_self 6 | //= require_tree ./channels 7 | 8 | (function() { 9 | this.App || (this.App = {}); 10 | 11 | App.cable = ActionCable.createConsumer(); 12 | 13 | }).call(this); 14 | -------------------------------------------------------------------------------- /app/views/treatment_entries/show.html.erb: -------------------------------------------------------------------------------- 1 |

TreatmentEntry#show

2 | Treatment date <%= @treatment_entry.date %>
3 | Treatment: <%= @treatment_entry.treatment %>
4 | Notes: <%= @treatment_entry.notes %>
5 | <%= link_to "Edit", edit_treatment_entry_path(@treatment_entry.id) %>
6 | <%= link_to "Delete", treatment_entry_path(:id => @treatment_entry.id), :method => :delete, data: { confirm: 'Are you sure?' } %>
7 | 8 | 9 | -------------------------------------------------------------------------------- /config/initializers/backtrace_silencers.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces. 4 | # Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ } 5 | 6 | # You can also remove all the silencers if you're trying to debug a problem that might stem from framework code. 7 | # Rails.backtrace_cleaner.remove_silencers! 8 | -------------------------------------------------------------------------------- /app/models/sponsor.rb: -------------------------------------------------------------------------------- 1 | class Sponsor < ApplicationRecord 2 | 3 | MINIMUM_AMOUNT_VALUE = 0 4 | 5 | belongs_to :cat 6 | belongs_to :user 7 | 8 | validates :start_date, presence: true 9 | validates :last_payment_date, presence: true 10 | validates :amount, presence: true 11 | validates_inclusion_of :renovate, in: [true, false] 12 | 13 | validates :amount, numericality: {greater_than: MINIMUM_AMOUNT_VALUE} 14 | validates_with SponsorValidator 15 | end 16 | -------------------------------------------------------------------------------- /app/policies/task_user_wizard_policy.rb: -------------------------------------------------------------------------------- 1 | class TaskUserWizardPolicy < ApplicationPolicy 2 | attr_reader :user, :task_user_wizard 3 | 4 | def initialize(user, task_user_wizard) 5 | @user = user 6 | @task_user_wizard = task_user_wizard 7 | end 8 | 9 | def assign_task_to_user_register? 10 | volunteer_or_admin? 11 | end 12 | 13 | def volunteer_or_admin? 14 | !@user.nil? && (@user.role == 'volunteer' || @user.role == 'admin') 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /app/views/devise/mailer/reset_password_instructions.html.erb: -------------------------------------------------------------------------------- 1 |

Hello <%= @resource.email %>!

2 | 3 |

Someone has requested a link to change your password. You can do this through the link below.

4 | 5 |

<%= link_to 'Change my password', edit_password_url(@resource, reset_password_token: @token) %>

6 | 7 |

If you didn't request this, please ignore this email.

8 |

Your password won't change until you access the link above and create a new one.

9 | -------------------------------------------------------------------------------- /app/models/colony.rb: -------------------------------------------------------------------------------- 1 | class Colony < ApplicationRecord 2 | MAXIMUM_NAME_COLONY_LENGTH = 20 3 | MAXIMUM_BIO_LENGTH = 512 4 | 5 | has_many :cats 6 | 7 | has_and_belongs_to_many :users 8 | 9 | has_many :assignments 10 | has_many :tasks, through: :assignments 11 | 12 | validates :name, presence: true 13 | validates :location, presence: true 14 | validates :name, length: {maximum: MAXIMUM_NAME_COLONY_LENGTH} 15 | validates :bio, length: {maximum: MAXIMUM_BIO_LENGTH} 16 | end 17 | -------------------------------------------------------------------------------- /app/validators/suffering_validator.rb: -------------------------------------------------------------------------------- 1 | class SufferingValidator < ActiveModel::Validator 2 | def validate(record) 3 | if !record.diagnosis_date.nil? && record.diagnosis_date > Date.today 4 | record.errors.add(:diagnosis_date, 'Diagnosis date must be in the past') 5 | end 6 | if record.status.eql?(4) && record.dischargement_date.nil? 7 | record.errors.add(:dischargement_date, 8 | 'Needs to be filled in for a healthy cat') 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /spec/models/illness_spec.rb: -------------------------------------------------------------------------------- 1 | require 'rails_helper' 2 | 3 | RSpec.describe Illness, type: :model do 4 | MAXIMUM_DESCRIPTION_LENGTH = 512 5 | 6 | it {should have_many :sufferings} 7 | 8 | context "validations" do 9 | it { should validate_presence_of(:name) } 10 | it { should validate_length_of(:name).is_at_most(20) } 11 | it { should validate_presence_of(:description) } 12 | it { should validate_length_of(:description).is_at_most(MAXIMUM_DESCRIPTION_LENGTH) } 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /app/views/layouts/application.html.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Conexión Felina 5 | <%= csrf_meta_tags %> 6 | 7 | 8 | <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %> 9 | <%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %> 10 | 11 | 12 | 13 | 14 | <%= yield %> 15 | 16 | -------------------------------------------------------------------------------- /spec/models/colony_spec.rb: -------------------------------------------------------------------------------- 1 | require "rails_helper" 2 | 3 | RSpec.describe Colony, type: :model do 4 | MAXIMUM_NAME_COLONY_LENGTH = 20 5 | 6 | it { should have_and_belong_to_many :users } 7 | it { should have_many :cats } 8 | it { should have_many :assignments } 9 | 10 | context "validations" do 11 | it { should validate_presence_of(:name) } 12 | it { should validate_presence_of(:location) } 13 | it { should validate_length_of(:name).is_at_most(MAXIMUM_NAME_COLONY_LENGTH) } 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /app/views/cats/new_sponsor.html.erb: -------------------------------------------------------------------------------- 1 |

Sponsor

2 | <%= form_tag sponsor_cat_path do %> 3 |
4 | <%= label_tag :amount %>
5 | <%= number_field_tag :amount, nil, min: 1, max: 666 %> 6 |
7 |
8 | <%= label_tag :renovate %>
9 | <%= hidden_field_tag :renovate, '0' %> 10 | <%= check_box_tag :renovate %> 11 |
12 | <%= hidden_field :id, params[:id] %> 13 |
14 |
15 | <%= submit_tag %> 16 |
17 | <% end %> 18 | -------------------------------------------------------------------------------- /app/views/devise/unlocks/new.html.erb: -------------------------------------------------------------------------------- 1 |

Resend unlock instructions

2 | 3 | <%= form_for(resource, as: resource_name, url: unlock_path(resource_name), html: { method: :post }) do |f| %> 4 | <%= devise_error_messages! %> 5 | 6 |
7 | <%= f.label :email %>
8 | <%= f.email_field :email, autofocus: true, autocomplete: "email" %> 9 |
10 | 11 |
12 | <%= f.submit "Resend unlock instructions" %> 13 |
14 | <% end %> 15 | 16 | <%= render "devise/shared/links" %> 17 | -------------------------------------------------------------------------------- /app/views/illnesses/edit.html.erb: -------------------------------------------------------------------------------- 1 |

Edit illness

2 | 3 | <%= form_for (@illness) do |f| %> 4 | 5 | <%= f.label :name %>
6 | <%= f.text_field :name %>

7 | 8 | <%= f.label :description %>
9 | <%= f.text_area :description %>

10 | 11 | <%= f.label :priority %>
12 | <%= f.select :priority, [:low, :medium, :high] %>

13 | 14 | <%= f.label :treatment %>
15 | <%= f.text_area :treatment %>

16 | 17 | <%= f.submit %> 18 | <% end %> 19 | 20 | -------------------------------------------------------------------------------- /app/views/illnesses/new.html.erb: -------------------------------------------------------------------------------- 1 |

Create a new illness

2 | 3 | <%= form_for (@illness) do |f| %> 4 | 5 | <%= f.label :name %>
6 | <%= f.text_field :name %>

7 | 8 | <%= f.label :description %>
9 | <%= f.text_area :description %>

10 | 11 | <%= f.label :priority %>
12 | <%= f.select :priority, [:low, :medium, :high] %>

13 | 14 | <%= f.label :treatment %>
15 | <%= f.text_area :treatment %>

16 | 17 | <%= f.submit %> 18 | <% end %> 19 | -------------------------------------------------------------------------------- /spec/models/sponsor_spec.rb: -------------------------------------------------------------------------------- 1 | require 'rails_helper' 2 | 3 | RSpec.describe Sponsor, type: :model do 4 | 5 | it { should belong_to :cat } 6 | it { should belong_to :user } 7 | 8 | context 'validations' do 9 | it {should validate_presence_of :start_date} 10 | it {should validate_presence_of :amount} 11 | it {should validate_numericality_of(:amount).is_greater_than(0)} 12 | it {should validate_presence_of :last_payment_date} 13 | it {should validate_inclusion_of(:renovate).in_array([true, false])} 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /app/views/devise/passwords/new.html.erb: -------------------------------------------------------------------------------- 1 |

Forgot your password?

2 | 3 | <%= form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :post }) do |f| %> 4 | <%= devise_error_messages! %> 5 | 6 |
7 | <%= f.label :email %>
8 | <%= f.email_field :email, autofocus: true, autocomplete: "email" %> 9 |
10 | 11 |
12 | <%= f.submit "Send me reset password instructions" %> 13 |
14 | <% end %> 15 | 16 | <%= render "devise/shared/links" %> 17 | -------------------------------------------------------------------------------- /app/views/cats/build/add_vet_info.html.erb: -------------------------------------------------------------------------------- 1 |

Info veterinaria

2 | <%= form_for(@cat, :url => wizard_path, :method => :put) do |f| %> 3 |
4 | <%= f.label :document %>
5 | <%= f.text_field :document, class: 'form-control' %> 6 |
7 |
8 | <%= f.label :sterilized %>
9 | <%= f.select(:sterilized, [['Yes', :yes], ['No', :no]], {:prompt => 'Select'}, {class: 'form-control'} ) %> 10 |
11 |
12 | <%= f.submit 'Siguiente', :class => 'btn btn-primary' %> 13 | <% end %> 14 | -------------------------------------------------------------------------------- /docs/_sidebar.md: -------------------------------------------------------------------------------- 1 | * [Home](/) 2 | * The project 3 | * [🎯 Mission](mission.md) 4 | * [🎨 Branding](branding.md) 5 | * [📐 UI/UX Specs](design.md) 6 | * User Guide 7 | * [🚀 App features](features.md) 8 | * Dev Specs 9 | * [🗃️ Database](database.md) 10 | * [🚨 User Authorization](pundit.md) 11 | * [👌 Conventions](conventions.md) 12 | * [📚 Learning Resources](learning.md) 13 | * Contributing 14 | * [💬 Join our Slack!](slack.md) 15 | * [💻 Installation](installation.md) 16 | * [🌍 Translations](i18n.md) 17 | * [🐾 Beginners Guide](beginners.md) -------------------------------------------------------------------------------- /config/initializers/wrap_parameters.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # This file contains settings for ActionController::ParamsWrapper which 4 | # is enabled by default. 5 | 6 | # Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array. 7 | ActiveSupport.on_load(:action_controller) do 8 | wrap_parameters format: [:json] 9 | end 10 | 11 | # To enable root element in JSON for ActiveRecord objects. 12 | # ActiveSupport.on_load(:active_record) do 13 | # self.include_root_in_json = true 14 | # end 15 | -------------------------------------------------------------------------------- /app/views/treatment_entries/edit.html.erb: -------------------------------------------------------------------------------- 1 |

TreatmentEntry#edit

2 | 3 | <%= form_for (@treatment_entry) do |f| %> 4 | 5 | <%= f.label :date %>
6 | <%= f.date_field :date %>

7 | 8 | <%= f.label :notes %>
9 | <%= f.text_area :notes %>

10 | 11 | <%= f.label :treatment %>
12 | <%= f.select :treatment, TreatmentEntry.treatments.keys.map { |w| [w.humanize, w] } %>
13 | 14 | <%= hidden_field_tag :suffering_id, params[:suffering_id] %>
15 | 16 | <%= f.submit %> 17 | <% end %> -------------------------------------------------------------------------------- /app/views/treatment_entries/new.html.erb: -------------------------------------------------------------------------------- 1 |

TreatmentEntry#new

2 | 3 | <%= form_for (@treatment_entry) do |f| %> 4 | 5 | <%= f.label :date %>
6 | <%= f.date_field :date %>

7 | 8 | <%= f.label :notes %>
9 | <%= f.text_area :notes %>

10 | 11 | <%= f.label :treatment %>
12 | <%= f.select :treatment, TreatmentEntry.treatments.keys.map { |w| [w.humanize, w] } %>
13 | 14 | <%= hidden_field_tag :suffering_id, params[:suffering_id] %>
15 | 16 | <%= f.submit %> 17 | <% end %> -------------------------------------------------------------------------------- /app/views/turns/index.html.erb: -------------------------------------------------------------------------------- 1 |

Turns#index

2 | <% @turns.each do |turn| %> 3 |
4 |
5 |
6 | Start date: <%= turn.start_date %>
7 | End date: <%= turn.end_date %>
8 | <%= link_to "Edit", edit_turn_path(id: turn.id, colony_id: @colony_id, assignment_id: @assignment_id) %>
9 | <%= link_to "Delete", turn_path(id: turn.id, colony_id: @colony_id ), :method => :delete, data: { confirm: 'Are you sure?' } %>
10 |
11 |
12 |
13 | <% end %> 14 | -------------------------------------------------------------------------------- /.codeclimate.yml: -------------------------------------------------------------------------------- 1 | --- 2 | plugins: 3 | brakeman: 4 | enabled: true 5 | bundler-audit: 6 | enabled: true 7 | csslint: 8 | enabled: true 9 | eslint: 10 | enabled: true 11 | exclude_paths: 12 | - public/ 13 | - vendor/ 14 | fixme: 15 | enabled: true 16 | exclude_patterns: 17 | - ".rubocop_enabled.yml" 18 | - ".rubocop.yml" 19 | rubocop: 20 | enabled: true 21 | config: '.rubocop.yml' 22 | 23 | ratings: 24 | paths: 25 | - Gemfile.lock 26 | - "**.erb" 27 | - "**.rb" 28 | - "**.css" 29 | - "**.js" 30 | exclude_paths: 31 | - config/ 32 | - db/ 33 | - spec/ -------------------------------------------------------------------------------- /app/policies/illness_policy.rb: -------------------------------------------------------------------------------- 1 | class IllnessPolicy < ApplicationPolicy 2 | attr_reader :user, :illness 3 | 4 | def initialize(user, illness) 5 | @user = user 6 | @illness = illness 7 | end 8 | 9 | def new? 10 | !@user.nil? && (@user.role == 'volunteer' || @user.role == 'admin') 11 | end 12 | 13 | def create? 14 | new? 15 | end 16 | 17 | def edit? 18 | new? 19 | end 20 | 21 | def update? 22 | new? 23 | end 24 | 25 | def destroy? 26 | new? 27 | end 28 | 29 | def show? 30 | !@user.nil? && (@user.role == "volunteer" || @user.role == "admin") 31 | end 32 | end 33 | -------------------------------------------------------------------------------- /app/views/devise/confirmations/new.html.erb: -------------------------------------------------------------------------------- 1 |

Resend confirmation instructions

2 | 3 | <%= form_for(resource, as: resource_name, url: confirmation_path(resource_name), html: { method: :post }) do |f| %> 4 | <%= devise_error_messages! %> 5 | 6 |
7 | <%= f.label :email %>
8 | <%= f.email_field :email, autofocus: true, autocomplete: "email", value: (resource.pending_reconfirmation? ? resource.unconfirmed_email : resource.email) %> 9 |
10 | 11 |
12 | <%= f.submit "Resend confirmation instructions" %> 13 |
14 | <% end %> 15 | 16 | <%= render "devise/shared/links" %> 17 | -------------------------------------------------------------------------------- /docs/pundit.md: -------------------------------------------------------------------------------- 1 | # User Authorization 2 | 3 | In our application there are three different types of user roles: 4 | * **Basic** users: they are allowed to browse most of cats info, 5 | adopt or sponsor a cat, and enroll as a volunteer. 6 | * **Volunteers**: they are able to do all basic users actions. 7 | Additionally, they may join a colony or create a new one to manage 8 | tasks, cats illnesses, sponsorships and adoptions. 9 | * **Admins**: they have full access over all colonies information, 10 | excluding all private information from users. 11 | 12 | User policies are managed with [Pundit gem](https://github.com/varvet/pundit) 13 | and are located under `app/policies`. -------------------------------------------------------------------------------- /app/views/assignments/index.html.erb: -------------------------------------------------------------------------------- 1 |

Assignments#index

2 | <% @assignments.each do |assignment| %> 3 |
4 |
5 |
6 |

Assigment: <%= assignment.id %>

7 | Colony: <%= Colony.find(assignment.colony_id).name %>
8 | Task: <%= Task.find(assignment.task_id).name%>
9 | <%= link_to "List of turns", turns_path(assignment_id: assignment.id, colony_id: @colony_id) %>
10 | <%= link_to "New turn", new_turn_path(assignment_id: assignment.id, colony_id: @colony_id) %>
11 |
12 |
13 |
14 | <% end %> 15 | -------------------------------------------------------------------------------- /app/views/cats/build/add_basic_info.html.erb: -------------------------------------------------------------------------------- 1 |

Info básica

2 | <%= form_for(@cat, :url => wizard_path, :method => :put) do |f| %> 3 |
4 | <%= f.label :name %>
5 | <%= f.text_field :name, class: 'form-control' %> 6 |
7 |
8 | <%= f.label :birthday_date %>
9 | <%= f.date_field :birthday_date, class: 'form-control' %> 10 |
11 |
12 | <%= f.label :gender %>
13 | <%= f.select(:gender, [['Male', :male], ['Female', :female]], {:prompt => 'Select'}, {class: 'form-control'} ) %> 14 |
15 |
16 | <%= f.submit 'Siguiente', :class => 'btn btn-primary' %> 17 | <% end %> 18 | -------------------------------------------------------------------------------- /config/initializers/assets.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Version of your assets, change this if you want to expire all your assets. 4 | Rails.application.config.assets.version = '1.0' 5 | 6 | # Add additional assets to the asset load path. 7 | # Rails.application.config.assets.paths << Emoji.images_path 8 | # Add Yarn node_modules folder to the asset load path. 9 | Rails.application.config.assets.paths << Rails.root.join('node_modules') 10 | 11 | # Precompile additional assets. 12 | # application.js, application.css, and all non-JS/CSS in the app/assets 13 | # folder are already added. 14 | # Rails.application.config.assets.precompile += %w( admin.js admin.css ) 15 | -------------------------------------------------------------------------------- /spec/models/product_spec.rb: -------------------------------------------------------------------------------- 1 | require 'rails_helper' 2 | 3 | RSpec.describe Product, type: :model do 4 | it{ should have_many :posessions } 5 | 6 | context 'validations' do 7 | it { should validate_presence_of(:name) } 8 | it { should validate_length_of(:name).is_at_most(50) } 9 | it { should validate_presence_of(:stock) } 10 | it { should validate_numericality_of(:stock).only_integer } 11 | it { should validate_numericality_of(:stock).is_greater_than_or_equal_to 0 } 12 | it { should validate_presence_of(:price) } 13 | it { should validate_numericality_of(:price).only_integer } 14 | it { should validate_numericality_of(:price).is_greater_than_or_equal_to 0 } 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /config/initializers/inflections.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new inflection rules using the following format. Inflections 4 | # are locale specific, and you may define rules for as many different 5 | # locales as you wish. All of these examples are active by default: 6 | # ActiveSupport::Inflector.inflections(:en) do |inflect| 7 | # inflect.plural /^(ox)$/i, '\1en' 8 | # inflect.singular /^(ox)en/i, '\1' 9 | # inflect.irregular 'person', 'people' 10 | # inflect.uncountable %w( fish sheep ) 11 | # end 12 | 13 | # These inflection rules are supported but not enabled by default: 14 | # ActiveSupport::Inflector.inflections(:en) do |inflect| 15 | # inflect.acronym 'RESTful' 16 | # end 17 | -------------------------------------------------------------------------------- /config/routes.rb: -------------------------------------------------------------------------------- 1 | Rails.application.routes.draw do 2 | devise_for :users 3 | 4 | resources :cats do 5 | resources :build, controller: 'cats/build' 6 | 7 | member do 8 | get 'adopt' 9 | get 'new_sponsor' 10 | post 'sponsor' 11 | end 12 | end 13 | 14 | resources :locations 15 | resources :colonies 16 | resources :sufferings 17 | resources :illnesses 18 | resources :tasks 19 | resources :assignments 20 | resources :turns 21 | resources :task_user_wizard do 22 | collection do 23 | post 'create' 24 | end 25 | end 26 | resources :treatment_entries 27 | 28 | HighVoltage.configure do |config| 29 | config.home_page = "home" 30 | config.layout = "pages" 31 | end 32 | end 33 | -------------------------------------------------------------------------------- /app/policies/turn_policy.rb: -------------------------------------------------------------------------------- 1 | class TurnPolicy < ApplicationPolicy 2 | attr_reader :user, :turn 3 | 4 | def initialize(user, turn) 5 | @user = user 6 | @turn = turn 7 | end 8 | 9 | def show? 10 | volunteer_or_admin? 11 | end 12 | 13 | def index? 14 | volunteer_or_admin? 15 | end 16 | 17 | def new? 18 | volunteer_or_admin? 19 | end 20 | 21 | def create? 22 | volunteer_or_admin? 23 | end 24 | 25 | def edit? 26 | volunteer_or_admin? 27 | end 28 | 29 | def update? 30 | volunteer_or_admin? 31 | end 32 | 33 | def destroy? 34 | volunteer_or_admin? 35 | end 36 | 37 | def volunteer_or_admin? 38 | !@user.nil? && (@user.role == 'volunteer' || @user.role == 'admin') 39 | end 40 | end 41 | -------------------------------------------------------------------------------- /app/views/sufferings/edit.html.erb: -------------------------------------------------------------------------------- 1 |

Update suffering

2 | 3 | <%= form_for (@suffering) do |f| %> 4 | 5 | <%= f.label :diagnosis_date %>
6 | <%= f.date_field :diagnosis_date %>

7 | 8 | <%= f.label :notes %>
9 | <%= f.text_area :notes %>

10 | 11 | <%= f.label :chronic %>
12 | <%= f.check_box :chronic %>
13 | 14 | <%= f.label :status %>
15 | <%= f.select :status, Suffering.statuses.keys.map { |w| [w.humanize, w] } %>
16 | 17 | <%= hidden_field_tag :cat_id, params[:cat_id] %> 18 | 19 | <%= f.label "Illness" %>
20 | <%= f.collection_select(:illness_id, Illness.all, :id, :name ) %>
21 | 22 | <%= link_to "New illness", new_illness_path %>
23 | 24 | <%= f.submit %> 25 | <% end %> -------------------------------------------------------------------------------- /config/application.rb: -------------------------------------------------------------------------------- 1 | require_relative 'boot' 2 | 3 | require 'rails/all' 4 | 5 | # Require the gems listed in Gemfile, including any gems 6 | # you've limited to :test, :development, or :production. 7 | Bundler.require(*Rails.groups) 8 | 9 | module ConexionFelina 10 | class Application < Rails::Application 11 | # Initialize configuration defaults for originally generated Rails version. 12 | config.load_defaults 5.1 13 | 14 | config.i18n.default_locale = :es 15 | # Settings in config/environments/* take precedence over those specified here. 16 | # Application configuration should go into files in config/initializers 17 | # -- all .rb files in that directory are automatically loaded. 18 | config.i18n.default_locale = :es 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /app/views/colonies/show.html.erb: -------------------------------------------------------------------------------- 1 |

<%= @colony.name %>

2 |

<%= @colony.bio %>

3 |
4 | <% @colony.tasks.each do | task | %> 5 | <%= link_to task.name, task_path( task.id ) %>
6 | <%= task.description %>
7 | <%= link_to "Assign this task to a user", new_task_user_wizard_path(task_id: task.id) %>
8 | <%= link_to "destroy", assignment_path(Assignment.where(colony_id:@colony.id, task_id:task.id).first), method: :delete %>
9 | <% end %> 10 | 11 | <%= link_to "List of Assignment", assignments_path(colony_id: @colony.id) %>
12 | <%= link_to "add assignment", new_assignment_path(colony_id: @colony.id) %>
13 | <%= link_to "edit", edit_colony_path(@colony.id) %>
14 | <%= link_to "destroy", colony_path(@colony.id), method: :delete %> -------------------------------------------------------------------------------- /app/views/sufferings/new.html.erb: -------------------------------------------------------------------------------- 1 |

create a new suffering

2 | 3 | <%= form_for (@suffering) do |f| %> 4 | 5 | <%= f.label :diagnosis_date %>
6 | <%= f.date_field :diagnosis_date %>

7 | 8 | <%= f.label :notes %>
9 | <%= f.text_area :notes %>

10 | 11 | <%= f.label :chronic %>
12 | <%= f.check_box :chronic %>
13 | 14 | <%= f.label :status %>
15 | <%= f.select :status, Suffering.statuses.keys.map { |w| [w.humanize, w] } %>
16 | 17 | <%= hidden_field_tag :cat_id, params[:cat_id] %> 18 | 19 | <%= f.label "Illness" %>
20 | <%= f.collection_select(:illness_id, Illness.all, :id, :name ) %>
21 | 22 | <%= link_to "New illness", new_illness_path %>
23 | 24 | <%= f.submit %> 25 | <% end %> -------------------------------------------------------------------------------- /app/views/devise/sessions/new.html.erb: -------------------------------------------------------------------------------- 1 |

Log in

2 | 3 | <%= form_for(resource, as: resource_name, url: session_path(resource_name)) do |f| %> 4 |
5 | <%= f.label :email %>
6 | <%= f.email_field :email, autofocus: true, autocomplete: "email" %> 7 |
8 | 9 |
10 | <%= f.label :password %>
11 | <%= f.password_field :password, autocomplete: "off" %> 12 |
13 | 14 | <% if devise_mapping.rememberable? -%> 15 |
16 | <%= f.check_box :remember_me %> 17 | <%= f.label :remember_me %> 18 |
19 | <% end -%> 20 | 21 |
22 | <%= f.submit "Log in" %> 23 |
24 | <% end %> 25 | 26 | <%= render "devise/shared/links" %> 27 | -------------------------------------------------------------------------------- /app/policies/suffering_policy.rb: -------------------------------------------------------------------------------- 1 | class SufferingPolicy < ApplicationPolicy 2 | attr_reader :user, :suffering 3 | 4 | def initialize(user, suffering) 5 | @user = user 6 | @suffering = suffering 7 | end 8 | 9 | def show? 10 | volunteer_or_admin? 11 | end 12 | 13 | def index? 14 | volunteer_or_admin? 15 | end 16 | 17 | def new? 18 | volunteer_or_admin? 19 | end 20 | 21 | def create? 22 | volunteer_or_admin? 23 | end 24 | 25 | def edit? 26 | volunteer_or_admin? 27 | end 28 | 29 | def update? 30 | volunteer_or_admin? 31 | end 32 | 33 | def destroy? 34 | volunteer_or_admin? 35 | end 36 | 37 | def volunteer_or_admin? 38 | !@user.nil? && (@user.role == "volunteer" || @user.role == "admin") 39 | end 40 | end 41 | -------------------------------------------------------------------------------- /app/views/treatment_entries/index.html.erb: -------------------------------------------------------------------------------- 1 |

TreatmentEntry#index

2 | <% @treatment_entries.each do |treatment_entry| %> 3 |
4 |
5 |
6 | Treatment date <%= treatment_entry.date %>
7 | Treatment: <%= treatment_entry.treatment %>
8 | Notes: <%= treatment_entry.notes %>
9 | <%= link_to 'Details', treatment_entry_path(treatment_entry.id) %>
10 | <%= link_to "Edit", edit_treatment_entry_path(treatment_entry.id) %>
11 | <%= link_to "Delete", treatment_entry_path(:id => treatment_entry.id), :method => :delete, data: { confirm: 'Are you sure?' } %>
12 |
13 |
14 |
15 | <% end %> 16 | -------------------------------------------------------------------------------- /app/views/task_user_wizard/new.html.erb: -------------------------------------------------------------------------------- 1 |

Assig Task to a User

2 | <%= form_tag("/task_user_wizard/create", method: "post") do %> 3 |

Select a Colony

4 | <%= select_tag "colony_id", options_from_collection_for_select(@colonies, "id", "name"), { :prompt => "Select a Colony"} %> 5 |

6 | 7 | <%= hidden_field_tag :task_id, params[:task_id] %> 8 | 9 |

Select a User

10 | <%= select_tag "user_id", options_from_collection_for_select(@users, "id", "username"), { :prompt => "Select a User"} %>
11 |
12 | 13 |

Make a turn

14 | Start Date 15 | <%= date_field(:turn, :start_date) %>
16 | End Date 17 | <%= date_field(:turn, :end_date) %>
18 | 19 | <%= submit_tag("Register a Task for a User") %> 20 | <% end %> 21 | 22 | -------------------------------------------------------------------------------- /app/policies/treatment_entry_policy.rb: -------------------------------------------------------------------------------- 1 | class TreatmentEntryPolicy < ApplicationPolicy 2 | attr_reader :user, :treatment_entry 3 | 4 | def initialize(user, treatment_entry) 5 | @user = user 6 | @treatment_entry = treatment_entry 7 | end 8 | 9 | def show? 10 | volunteer_or_admin? 11 | end 12 | 13 | def index? 14 | volunteer_or_admin? 15 | end 16 | 17 | def new? 18 | volunteer_or_admin? 19 | end 20 | 21 | def create? 22 | volunteer_or_admin? 23 | end 24 | 25 | def edit? 26 | volunteer_or_admin? 27 | end 28 | 29 | def update? 30 | volunteer_or_admin? 31 | end 32 | 33 | def destroy? 34 | volunteer_or_admin? 35 | end 36 | 37 | def volunteer_or_admin? 38 | !@user.nil? && (@user.role == 'volunteer' || @user.role == 'admin') 39 | end 40 | end 41 | -------------------------------------------------------------------------------- /app/policies/cat_policy.rb: -------------------------------------------------------------------------------- 1 | class CatPolicy < ApplicationPolicy 2 | attr_reader :user, :cat 3 | 4 | def initialize(user, cat) 5 | @user = user 6 | @cat = cat 7 | end 8 | 9 | def index? 10 | true 11 | end 12 | 13 | def new? 14 | volunteer_or_admin? 15 | end 16 | 17 | def create? 18 | volunteer_or_admin? 19 | end 20 | 21 | def update? 22 | volunteer_or_admin? 23 | end 24 | 25 | def edit? 26 | volunteer_or_admin? 27 | end 28 | 29 | def destroy? 30 | volunteer_or_admin? 31 | end 32 | 33 | def adopt? 34 | @user 35 | end 36 | 37 | def new_sponsor? 38 | @user 39 | end 40 | 41 | def sponsor? 42 | @user 43 | end 44 | 45 | def volunteer_or_admin? 46 | !@user.nil? && (@user.role == "volunteer" || @user.role == "admin") 47 | end 48 | end 49 | -------------------------------------------------------------------------------- /spec/validators/turn_validator_spec.rb: -------------------------------------------------------------------------------- 1 | require "rails_helper" 2 | 3 | RSpec.describe TurnValidator do 4 | def mock_relationships(turn) 5 | turn.assignment = mock_model("Assignment") 6 | end 7 | 8 | context "given a turn with a start date earlier than its end date" do 9 | it "must be valid" do 10 | valid_turn = Turn.new(start_date: Date.yesterday, end_date: Date.today) 11 | mock_relationships(valid_turn) 12 | 13 | expect(valid_turn).to be_valid 14 | end 15 | end 16 | 17 | context "given a turn with a start date later than its end date" do 18 | it "must be invalid" do 19 | invalid_turn = Turn.new(start_date: Date.today, end_date: Date.yesterday) 20 | mock_relationships(invalid_turn) 21 | 22 | expect(invalid_turn).to_not be_valid 23 | end 24 | end 25 | end 26 | -------------------------------------------------------------------------------- /spec/factories.rb: -------------------------------------------------------------------------------- 1 | FactoryBot.define do 2 | 3 | factory :user do 4 | username { "Joe" } 5 | email { "joe@gmail.com" } 6 | password { "blahblah2" } 7 | password_confirmation { "blahblah2" } 8 | bio { "Hello world!" } 9 | purrs { 0 } 10 | 11 | trait :volunteer do 12 | role { :volunteer } 13 | end 14 | 15 | trait :basic do 16 | role { :basic } 17 | end 18 | 19 | trait :admin do 20 | role { :admin } 21 | end 22 | end 23 | 24 | 25 | factory :location do 26 | name { "valencia" } 27 | end 28 | 29 | factory :colony do 30 | name { "viveros" } 31 | location 32 | end 33 | 34 | factory :cat do 35 | name { "Joe" } 36 | bio { "Hello world" } 37 | saved_state { "active" } 38 | birthday_date { Date.yesterday } 39 | colony 40 | end 41 | end -------------------------------------------------------------------------------- /spec/validators/adoption_validator_spec.rb: -------------------------------------------------------------------------------- 1 | require "rails_helper" 2 | 3 | RSpec.describe Adoption, :type => :model do 4 | def mock_relationships(adoption) 5 | adoption.user = mock_model("User") 6 | adoption.cat = mock_model("Cat") 7 | end 8 | 9 | context "given a adoption with date" do 10 | it "must be valid" do 11 | valid_adoption = Adoption.new(date: Date.yesterday) 12 | mock_relationships(valid_adoption) 13 | 14 | expect(valid_adoption).to be_valid 15 | end 16 | end 17 | 18 | context "given a adoption without date when updated" do 19 | it "must be invalid" do 20 | valid_adoption = Adoption.new() 21 | valid_adoption.update({}) 22 | mock_relationships(valid_adoption) 23 | 24 | expect(valid_adoption.errors.messages.empty?).to eq(false) 25 | end 26 | end 27 | end -------------------------------------------------------------------------------- /app/views/sufferings/show.html.erb: -------------------------------------------------------------------------------- 1 |

Diagnosis date: <%= @suffering.diagnosis_date %>

2 |

Notes: <%= @suffering.notes %>

3 |

Chronic: <%= @suffering.chronic %>

4 |

Status: <%= @suffering.status %>

5 |

<%= link_to "Cat profile", cat_path(@suffering.cat_id) %>

6 |

<%= link_to "Illness info", illness_path(@suffering.illness_id) %>

7 |

<%= link_to "Treatment Entries", treatment_entries_path(:suffering_id => @suffering.id) %>

8 |

<%= link_to "New Treatment Entry", new_treatment_entry_path(:suffering_id => @suffering.id) %>

9 |

<%= link_to "Edit", edit_suffering_path(@suffering.id) %>

10 |

<%= link_to "Delete", suffering_path(:id => @suffering.id), :method => :delete, data: { confirm: 'Are you sure?' } %>

11 | 12 | 13 | -------------------------------------------------------------------------------- /app/controllers/tasks_controller.rb: -------------------------------------------------------------------------------- 1 | class TasksController < ApplicationController 2 | def index 3 | @tasks = Task.all 4 | end 5 | 6 | def new 7 | @task = Task.new 8 | end 9 | 10 | def edit 11 | @task = Task.find(params[:id]) 12 | end 13 | 14 | def create 15 | @task = Task.new(task_params) 16 | @task.save 17 | redirect_to(tasks_path) 18 | end 19 | 20 | def update 21 | @task = Task.find(params[:id]) 22 | @task.update(task_params) 23 | redirect_to(tasks_path) 24 | end 25 | 26 | def show 27 | @task = Task.find(params[:id]) 28 | end 29 | 30 | def destroy 31 | @task = Task.find(params[:id]) 32 | @task.destroy 33 | redirect_to(tasks_path) 34 | end 35 | 36 | private 37 | 38 | def task_params 39 | params.require(:task).permit(:name, :description) 40 | end 41 | end 42 | -------------------------------------------------------------------------------- /docs/slack.md: -------------------------------------------------------------------------------- 1 | # Join our Slack space! 2 | 3 | If you are interested in contributing to our project, you can 4 | [send us a message](mailto:hola@infusionvlc.com) and we'll send you an 5 | invitation to INFUSIÓN's slack space. :tada: 6 | 7 | In case you don't know what **[INFUSIÓN](www.infusionvlc.com)** is, 8 | it's a **community** based in **València (Spain)** in which everyone 9 | is encouraged to participate, share their knowledge and learn from others. 10 | Our goal is to get **technology** closer to people, regardless of their 11 | previous knowledge, through meetups and projects. 12 | 13 | We believe that diversity is a source of wealth in all areas and that is 14 | why we want to **welcome all people**, whatever their, gender, age, experience, 15 | origin, etc. 👱🧔🏽👨🌾👵 Therefore, everyone involved in the community must 16 | comply with our code of conduct. 🖐️ -------------------------------------------------------------------------------- /app/controllers/assignments_controller.rb: -------------------------------------------------------------------------------- 1 | class AssignmentsController < ApplicationController 2 | def index 3 | @colony_id = params[:colony_id] 4 | @assignments = Assignment.where(colony_id: @colony_id) 5 | end 6 | 7 | def new 8 | @assignment = Assignment.new(colony_id: params[:colony_id]) 9 | end 10 | 11 | def create 12 | @assignment = Assignment.new(assignment_params) 13 | @assignment.save 14 | redirect_to(colony_path(@assignment.colony_id)) 15 | end 16 | 17 | def show 18 | @assignment = Assignment.find(params[:id]) 19 | end 20 | 21 | def destroy 22 | @assignment = Assignment.find(params[:id]) 23 | @assignment.destroy 24 | redirect_to(colony_path(@assignment.colony_id)) 25 | end 26 | 27 | private 28 | 29 | def assignment_params 30 | params.require(:assignment).permit(:colony_id, :task_id) 31 | end 32 | end 33 | -------------------------------------------------------------------------------- /app/policies/application_policy.rb: -------------------------------------------------------------------------------- 1 | class ApplicationPolicy 2 | attr_reader :user, :record 3 | 4 | def initialize(user, record) 5 | @user = user 6 | @record = record 7 | end 8 | 9 | def index? 10 | false 11 | end 12 | 13 | def show? 14 | scope.where(:id => record.id).exists? 15 | end 16 | 17 | def create? 18 | false 19 | end 20 | 21 | def new? 22 | create? 23 | end 24 | 25 | def update? 26 | false 27 | end 28 | 29 | def edit? 30 | update? 31 | end 32 | 33 | def destroy? 34 | false 35 | end 36 | 37 | def scope 38 | Pundit.policy_scope!(user, record.class) 39 | end 40 | 41 | class Scope 42 | attr_reader :user, :scope 43 | 44 | def initialize(user, scope) 45 | @user = user 46 | @scope = scope 47 | end 48 | 49 | def resolve 50 | scope 51 | end 52 | end 53 | end 54 | -------------------------------------------------------------------------------- /app/assets/javascripts/application.js: -------------------------------------------------------------------------------- 1 | // This is a manifest file that'll be compiled into application.js, which will include all the files 2 | // listed below. 3 | // 4 | // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, or any plugin's 5 | // vendor/assets/javascripts directory can be referenced here using a relative path. 6 | // 7 | // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the 8 | // compiled file. JavaScript code in this file should be added after the last require_* statement. 9 | // 10 | // Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details 11 | // about supported directives. 12 | // 13 | //= require rails-ujs 14 | //= require turbolinks 15 | //= require jquery3 16 | //= require popper 17 | //= require bootstrap-sprockets 18 | //= require cocoon 19 | //= require_tree . 20 | -------------------------------------------------------------------------------- /app/controllers/task_user_wizard_controller.rb: -------------------------------------------------------------------------------- 1 | class TaskUserWizardController < ApplicationController 2 | def new 3 | @colonies = Colony.all 4 | @tasks = Task.all 5 | @users = User.all 6 | end 7 | 8 | def create 9 | assignment = Assignment.new 10 | assignment.colony_id = params[:colony_id] 11 | assignment.task_id = params[:task_id] 12 | assignment.save 13 | 14 | user = User.find(params[:user_id]) 15 | puts user.username 16 | 17 | turn = Turn.new(turn_params) 18 | turn.assignment_id = assignment.id 19 | turn.save 20 | 21 | turns_users = TurnsUser.new 22 | turns_users.user_id = user.id 23 | turns_users.turn_id = turn.id 24 | turns_users.save 25 | 26 | redirect_to(cats_path) 27 | end 28 | 29 | private 30 | 31 | def turn_params 32 | params.require(:turn).permit(:start_date, :end_date) 33 | end 34 | end 35 | -------------------------------------------------------------------------------- /docs/features.md: -------------------------------------------------------------------------------- 1 | # App features 2 | 3 | 🚧 **Note: this section is still a work in progress...** 4 | 5 | ## Basic user features 6 | * User authentication & profile management 7 | * Browse cats in colonies 8 | * Adopt a cat 9 | * Contact colony volunteers 10 | * Sponsor a cat 11 | * Send messages to volunteers who take care of him/her 12 | * Manage sponsorship subscription 13 | * Browse colonies and locations 14 | * Enroll as a volunteer 15 | * Join a colony 16 | * Create a new colony 17 | 18 | ## Volunteer features 19 | * Join a colony (can join more than one) 20 | * Manage a colony's tasks 21 | * Manage all cats information in a colony 22 | * Keep track of a cat's health condition 23 | * Send updates to sponsors about their supported cats 24 | * Manage sponsorships and adoptions 25 | 26 | ## Admin features 27 | Admins are able to do any action that a volunteer is allowed to do in any colony. -------------------------------------------------------------------------------- /bin/update: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby.exe 2 | require 'pathname' 3 | require 'fileutils' 4 | include FileUtils 5 | 6 | # path to your application root. 7 | APP_ROOT = Pathname.new File.expand_path('..', __dir__) 8 | 9 | def system!(*args) 10 | system(*args) || abort("\n== Command #{args} failed ==") 11 | end 12 | 13 | chdir APP_ROOT do 14 | # This script is a way to update your development environment automatically. 15 | # Add necessary update steps to this file. 16 | 17 | puts '== Installing dependencies ==' 18 | system! 'gem install bundler --conservative' 19 | system('bundle check') || system!('bundle install') 20 | 21 | puts "\n== Updating database ==" 22 | system! 'bin/rails db:migrate' 23 | 24 | puts "\n== Removing old logs and tempfiles ==" 25 | system! 'bin/rails log:clear tmp:clear' 26 | 27 | puts "\n== Restarting application server ==" 28 | system! 'bin/rails restart' 29 | end 30 | -------------------------------------------------------------------------------- /app/controllers/colonies_controller.rb: -------------------------------------------------------------------------------- 1 | class ColoniesController < ApplicationController 2 | def index 3 | @colonies = Colony.all 4 | end 5 | 6 | def new 7 | @colony = Colony.new 8 | end 9 | 10 | def edit 11 | @colony = Colony.find(params[:id]) 12 | end 13 | 14 | def create 15 | @colony = Colony.new(colonies_params) 16 | @colony.save 17 | redirect_to(colonies_path) 18 | end 19 | 20 | def update 21 | @colony = Colony.find(params[:id]) 22 | @colony.update(colonies_params) 23 | redirect_to(colonies_path) 24 | end 25 | 26 | def show 27 | @colony = Colony.find(params[:id]) 28 | end 29 | 30 | def destroy 31 | @colony = Colony.find(params[:id]) 32 | @colony.destroy 33 | redirect_to(colonies_path) 34 | end 35 | 36 | private 37 | 38 | def colonies_params 39 | params.require(:colony).permit(:name, :bio, :location_id) 40 | end 41 | end 42 | -------------------------------------------------------------------------------- /app/views/devise/passwords/edit.html.erb: -------------------------------------------------------------------------------- 1 |

Change your password

2 | 3 | <%= form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :put }) do |f| %> 4 | <%= devise_error_messages! %> 5 | <%= f.hidden_field :reset_password_token %> 6 | 7 |
8 | <%= f.label :password, "New password" %>
9 | <% if @minimum_password_length %> 10 | (<%= @minimum_password_length %> characters minimum)
11 | <% end %> 12 | <%= f.password_field :password, autofocus: true, autocomplete: "off" %> 13 |
14 | 15 |
16 | <%= f.label :password_confirmation, "Confirm new password" %>
17 | <%= f.password_field :password_confirmation, autocomplete: "off" %> 18 |
19 | 20 |
21 | <%= f.submit "Change my password" %> 22 |
23 | <% end %> 24 | 25 | <%= render "devise/shared/links" %> 26 | -------------------------------------------------------------------------------- /docs/design.md: -------------------------------------------------------------------------------- 1 | # UI/UX Specs 2 | 3 | User experience and usability is a must for this project. Volunteers who are 4 | part of cat colonies usually don't have too much time nor resources for 5 | managing the cats' info, so the interface is intended to be really clear and 6 | straightforward. 🖐️ 7 | 8 | If you find any issue, don't hesitate to 9 | [send us a message](mailto:hola@infusionvlc.com)or open up a new issue in our 10 | [GitHub repo](https://github.com/infusionvlc/ConexionFelina). :mag: 11 | 12 | ## UI mock-ups 13 | 14 | All application mockups can be found in our 15 | [Figma document](https://www.figma.com/file/PuezufmBksh475JS5nvBsSkx/ConexionFelina?node-id=0%3A1). 16 | This file intends to be our app's design ground truth and must be followed when 17 | developing any component or feature. If you find any mistake or have any 18 | suggestion, please open up a new issue 19 | [GitHub repo](https://github.com/infusionvlc/ConexionFelina) :warning: 20 | 21 | ![Sample UI mock-up](assets/ui_sample.png) -------------------------------------------------------------------------------- /spec/models/user_spec.rb: -------------------------------------------------------------------------------- 1 | require 'rails_helper' 2 | 3 | RSpec.describe User, type: :model do 4 | it { should have_and_belong_to_many :colonies} 5 | it { should have_and_belong_to_many :turns} 6 | it { should have_many :sponsors} 7 | it { should have_many :adoptions} 8 | it { should have_many :donations} 9 | it { should have_many :posessions} 10 | 11 | context 'validations' do 12 | it { should validate_presence_of(:username) } 13 | it { should validate_presence_of(:email) } 14 | it { should validate_presence_of(:role) } 15 | it { should validate_presence_of(:purrs) } 16 | it { should validate_numericality_of(:purrs).only_integer } 17 | it { should validate_numericality_of(:purrs).is_greater_than_or_equal_to 0 } 18 | it { should validate_length_of(:username).is_at_most(20) } 19 | it { should validate_length_of(:bio).is_at_most(512) } 20 | it { should validate_uniqueness_of(:email).case_insensitive } 21 | it { should validate_uniqueness_of(:username) } 22 | end 23 | end 24 | -------------------------------------------------------------------------------- /app/controllers/locations_controller.rb: -------------------------------------------------------------------------------- 1 | class LocationsController < ApplicationController 2 | def index 3 | @locations = Location.all 4 | end 5 | 6 | def new 7 | @location = Location.new 8 | end 9 | 10 | def edit 11 | @location = Location.find( params[ :id ]) 12 | end 13 | 14 | def create 15 | @location = Location.new( location_params ) 16 | @location.save 17 | redirect_to( locations_path ) 18 | end 19 | 20 | def update 21 | @location = Location.find( params[ :id ]) 22 | @location.update(location_params) 23 | redirect_to( locations_path ) 24 | end 25 | 26 | def show 27 | @location = Location.find( params[ :id ]) 28 | end 29 | 30 | def destroy 31 | @location = Location.find(params[:id]) 32 | @location.destroy 33 | redirect_to(locations_path) 34 | end 35 | 36 | private 37 | 38 | def location_params 39 | params.require(:location).permit(:name, :description, :address, :longitude, :latitude) 40 | end 41 | end 42 | -------------------------------------------------------------------------------- /config/locales/en.yml: -------------------------------------------------------------------------------- 1 | # Files in the config/locales directory are used for internationalization 2 | # and are automatically loaded by Rails. If you want to use locales other 3 | # than English, add the necessary files in this directory. 4 | # 5 | # To use the locales, use `I18n.t`: 6 | # 7 | # I18n.t 'hello' 8 | # 9 | # In views, this is aliased to just `t`: 10 | # 11 | # <%= t('hello') %> 12 | # 13 | # To use a different locale, set it with `I18n.locale`: 14 | # 15 | # I18n.locale = :es 16 | # 17 | # This would use the information in config/locales/es.yml. 18 | # 19 | # The following keys must be escaped otherwise they will not be retrieved by 20 | # the default I18n backend: 21 | # 22 | # true, false, on, off, yes, no 23 | # 24 | # Instead, surround them with single quotes. 25 | # 26 | # en: 27 | # 'true': 'foo' 28 | # 29 | # To learn more, please read the Rails Internationalization guide 30 | # available at http://guides.rubyonrails.org/i18n.html. 31 | 32 | en: 33 | hello: "Hello world" 34 | -------------------------------------------------------------------------------- /docs/beginners.md: -------------------------------------------------------------------------------- 1 | # Beginners Guide 2 | 3 | If you have any questions, don't hesitate to contact the team via mail or open up an issue. :wink: 4 | 5 | ## How to properly submit a PR 6 | 1. Fork and clone the repo to your computer. If you haven't done it yet, set up the upstream remote `git remote add upstream https://github.com/infusionvlc/ConexionFelina` 7 | 3. **Make sure you're on the master branch (`git checkout master`) and you are up to date with `git status`**. If not: 8 | `git pull upstream master` 9 | 4. Create a separate branch with the name of the issue you are going to work in with `git checkout -b ` 10 | 5. Commit your changes. 11 | 6. Push the working branch to your remote fork. 12 | 7. Make a PR on the upstream master branch with "closes #XX" at it's title to automatically close the issue. **Do not merge it with the master branch on your fork**. 13 | 8. If there is anything that needs to be changed it will be commented on the PR. 14 | 9. When everything is okay your PR will be merged! 15 | -------------------------------------------------------------------------------- /app/views/sufferings/index.html.erb: -------------------------------------------------------------------------------- 1 |

Suffering#index

2 | <% @sufferings.each do |suffering| %> 3 | <% 4 | cat = Cat.find(suffering.cat_id) 5 | illness = Illness.find(suffering.illness_id) 6 | %> 7 |
8 |
9 |
10 | Diagnosis date <%= suffering.diagnosis_date %>
11 | Notes: <%= suffering.notes %>
12 | Is chronic: <%= suffering.chronic %>
13 | Status: <%= suffering.status %>
14 | Cat: <%= cat.name %>
15 | Illness: <%= illness.name %>
16 | <%= link_to 'Details', suffering_path(suffering.id) %>
17 | <% if policy(@sufferings).volunteer_or_admin? %> 18 | <%= link_to "Edit", edit_suffering_path(suffering.id) %>
19 | <%= link_to "Delete", suffering_path(:id => suffering.id), :method => :delete, data: { confirm: 'Are you sure?' } %>
20 | <% end %> 21 |
22 |
23 |
24 | <% end %> 25 | -------------------------------------------------------------------------------- /docs/mission.md: -------------------------------------------------------------------------------- 1 | # Mission & principles 2 | 3 | ## Mission 4 | 5 | This project is part of [INFUSIÓN](www.infusionvlc.com). In case you don't know 6 | what **INFUSIÓN** is, it's a **community** based in **València (Spain)** in 7 | which everyone is encouraged to participate, share their knowledge and learn 8 | from others. Our goal is to get **technology** closer to people, regardless of 9 | their previous knowledge, through meetups and projects. 10 | 11 | We believe that diversity is a source of wealth in all areas and that is why we 12 | want to **welcome all people**, whatever their, gender, age, experience, origin, 13 | etc. 👱🧔🏽👨🌾👵 Therefore, everyone involved in the community must comply with 14 | our code of conduct. 🖐️ 15 | 16 | 17 | ## Principles 18 | 19 | Our main goal is to build up a project that has a real purpose and impacts on 20 | society. During this process, we encourage every contributor's **learning** 21 | process, proactivity and **social skills**. We do our best to learn about 22 | coding **best practices**, team **organization** and web development while 23 | having fun. -------------------------------------------------------------------------------- /spec/validators/donation_validator_spec.rb: -------------------------------------------------------------------------------- 1 | require "rails_helper" 2 | 3 | RSpec.describe DonationValidator do 4 | def mock_relationships(donation) 5 | donation.user = mock_model("User") 6 | end 7 | 8 | context "given a donation with its date earlier than today" do 9 | it "must be valid" do 10 | valid_donation = Donation.new(amount: 1, date: Date.yesterday) 11 | mock_relationships(valid_donation) 12 | 13 | expect(valid_donation).to be_valid 14 | end 15 | end 16 | 17 | context "given a donation with its date equal to today" do 18 | it "must be valid" do 19 | valid_donation = Donation.new(amount: 1, date: Date.today) 20 | mock_relationships(valid_donation) 21 | 22 | expect(valid_donation).to be_valid 23 | end 24 | end 25 | 26 | context "given a donation with it date later than today" do 27 | it "must be invalid" do 28 | invalid_donation = Donation.new(amount: 1, date: Date.tomorrow) 29 | mock_relationships(invalid_donation) 30 | 31 | expect(invalid_donation).to_not be_valid 32 | end 33 | end 34 | end 35 | -------------------------------------------------------------------------------- /app/models/user.rb: -------------------------------------------------------------------------------- 1 | class User < ApplicationRecord 2 | # Include default devise modules. Others available are: 3 | # :confirmable, :lockable, :timeoutable and :omniauthable 4 | devise :database_authenticatable, :registerable, 5 | :recoverable, :rememberable, :trackable, :validatable 6 | 7 | MAXIMUM_USERNAME_LENGTH = 20 8 | MAXIMUM_BIO_LENGTH = 512 9 | MINIMUM_PURR_VALUE = 0 10 | 11 | enum role: [ :admin, :volunteer, :basic] 12 | 13 | has_and_belongs_to_many :colonies 14 | has_and_belongs_to_many :turns 15 | has_many :posessions 16 | has_many :donations 17 | has_many :adoptions 18 | has_many :cats, through: :adoptions 19 | has_many :sponsors 20 | has_many :cats, through: :sponsors 21 | 22 | validates :username, :email, :role, :purrs, presence: true 23 | validates :username, length: { maximum: MAXIMUM_USERNAME_LENGTH } 24 | validates :bio, length: { maximum: MAXIMUM_BIO_LENGTH } 25 | validates :purrs, numericality: { only_integer: true, greater_than_or_equal_to: MINIMUM_PURR_VALUE } 26 | validates :email, uniqueness: true 27 | validates :username, uniqueness: true 28 | end 29 | -------------------------------------------------------------------------------- /app/views/cats/build/_suffering_fields.html.erb: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |
5 | <%= f.label :status %>
6 | <%= f.select :status, Suffering.statuses.keys.map { |w| [w.humanize, w] } %>
7 | 8 | <%= f.hidden_field :cat_id, value: params[:cat_id] %> 9 | 10 | <%= f.label "Illness" %>
11 | <%= f.collection_select(:illness_id, Illness.all, :id, :name ) %>
12 | 13 | <%= f.check_box :chronic %> 14 | <%= f.label :chronic %>
15 | 16 | <%= f.label :diagnosis_date %>
17 | <%= f.date_field :diagnosis_date, class: 'form-control' %> 18 | 19 | <%= f.label :notes %>
20 | <%= f.text_area :notes, class:'form-control' %>
21 |
22 |
23 | <%= link_to_remove_association f, {class:'btn btn-danger', aria: {label:"#{I18n.t 'main.remove'}"}} do %>Remove<% end %> 24 |
25 |
26 |
27 |
-------------------------------------------------------------------------------- /spec/validators/posession_validator_spec.rb: -------------------------------------------------------------------------------- 1 | require 'rails_helper' 2 | 3 | RSpec.describe PosessionValidator do 4 | def mock_relationships(posession) 5 | posession.user = mock_model("User") 6 | posession.product = mock_model("Product") 7 | end 8 | 9 | context 'given a posession with a date earlier than today' do 10 | it 'must be valid' do 11 | valid_posession = Posession.new(date: Date.yesterday) 12 | 13 | mock_relationships(valid_posession) 14 | expect(valid_posession).to be_valid 15 | end 16 | end 17 | 18 | context 'given a posession with a date later than today' do 19 | it 'must be invalid' do 20 | invalid_posession = Posession.new(date: Date.today) 21 | 22 | mock_relationships(invalid_posession) 23 | expect(invalid_posession).to_not be_valid 24 | end 25 | end 26 | 27 | context 'given a posession with a date being nil' do 28 | it 'must be invalid' do 29 | invalid_posession = Posession.new(date: Date.today) 30 | 31 | mock_relationships(invalid_posession) 32 | expect(invalid_posession).to_not be_valid 33 | end 34 | end 35 | end -------------------------------------------------------------------------------- /app/views/cats/new.html.erb: -------------------------------------------------------------------------------- 1 | 2 |

New cat

3 | <%= form_for(@cat) do |f| %> 4 |
5 | <%= f.label :bio %>
6 | <%= f.text_area :bio%> 7 |
8 |
9 | <%= f.label :birthday_date %>
10 | <%= f.date_field :birthday_date %> 11 |
12 |
13 | <%= f.label :gender %>
14 | <%= f.select(:gender, [['Male', :male], ['Female', :female]], :prompt => 'Select') %> 15 |
16 |
17 | <%= f.label :sterilized %>
18 | <%= f.select(:sterilized, [['Yes', :yes], ['No', :no]], :prompt => 'Select') %> 19 |
20 |
21 | <%= f.label :abandoned_date %>
22 | <%= f.date_field :abandoned_date %> 23 |
24 |
25 | <%= f.label :document %>
26 | <%= f.text_field :document %> 27 |
28 |
29 | <%= f.label :colony_id %>
30 | <%= f.select(:colony_id, Colony.all.collect {|u| [u.name, u.id]}, :prompt => 'Select') %> 31 |
32 |
33 |
34 | <%= f.submit %> 35 |
36 | <% end %> -------------------------------------------------------------------------------- /bin/setup: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby.exe 2 | require 'pathname' 3 | require 'fileutils' 4 | include FileUtils 5 | 6 | # path to your application root. 7 | APP_ROOT = Pathname.new File.expand_path('..', __dir__) 8 | 9 | def system!(*args) 10 | system(*args) || abort("\n== Command #{args} failed ==") 11 | end 12 | 13 | chdir APP_ROOT do 14 | # This script is a starting point to setup your application. 15 | # Add necessary setup steps to this file. 16 | 17 | puts '== Installing dependencies ==' 18 | system! 'gem install bundler --conservative' 19 | system('bundle check') || system!('bundle install') 20 | 21 | # Install JavaScript dependencies if using Yarn 22 | # system('bin/yarn') 23 | 24 | # puts "\n== Copying sample files ==" 25 | # unless File.exist?('config/database.yml') 26 | # cp 'config/database.yml.sample', 'config/database.yml' 27 | # end 28 | 29 | puts "\n== Preparing database ==" 30 | system! 'bin/rails db:setup' 31 | 32 | puts "\n== Removing old logs and tempfiles ==" 33 | system! 'bin/rails log:clear tmp:clear' 34 | 35 | puts "\n== Restarting application server ==" 36 | system! 'bin/rails restart' 37 | end 38 | -------------------------------------------------------------------------------- /app/views/pages/learn.html.erb: -------------------------------------------------------------------------------- 1 |
2 |

¡Colonia a la vista!

3 |
4 | 5 | 6 | 7 |
8 |
9 | 10 |
11 |
12 |
13 |

<%= t 'landing.learn.manifest' %>

14 | 15 |
    16 |
  1. <%= t 'landing.learn.article0' %>
  2. 17 |
  3. <%= t 'landing.learn.article1' %>
  4. 18 |
  5. <%= t 'landing.learn.article2' %>
  6. 19 |
  7. <%= t 'landing.learn.article3' %>
  8. 20 |
  9. <%= t 'landing.learn.article4' %>
  10. 21 |
22 |
23 |
24 |
25 | 26 |
27 |
28 |
-------------------------------------------------------------------------------- /app/views/cats/index.html.erb: -------------------------------------------------------------------------------- 1 |

Los miembros de la colonia

2 | <% @cats.each do |cat| %> 3 |
4 |
5 |
6 | <%= image_tag(cat.avatar) if cat.avatar %> 7 | <%= link_to cat.name, cat_path(cat.id) %> 8 |
9 |
10 | <%= cat.bio %>
11 | <%= I18n.t 'cats.birthDate'%> <%= cat.birthday_date %>
12 | <%= I18n.t 'cats.gender'%> <%= cat.gender %>
13 | <%= I18n.t 'cats.sterilized'%> <%= cat.sterilized %>
14 | <% if !cat.abandoned_date.nil?%> 15 | <%= I18n.t 'cats.abandonedDate'%> <%= cat.abandoned_date %>
16 | <% end %> 17 | <%= I18n.t 'cats.document'%> <%= cat.document %>
18 | <% if policy(cat).volunteer_or_admin? %> 19 | <%= link_to "Edit", edit_cat_path(cat.id) %>
20 | <%= link_to "Destroy", cat_path(cat.id), method: :delete %>
21 | <%= link_to "List of sufferings", sufferings_path(:cat_id => cat.id) %>
22 | <%= link_to "New suffering", new_suffering_path(:cat_id => cat.id) %>
23 | <% end %> 24 |
25 |
26 |
27 | <% end %> 28 | -------------------------------------------------------------------------------- /app/views/devise/shared/_links.html.erb: -------------------------------------------------------------------------------- 1 | <%- if controller_name != 'sessions' %> 2 | <%= link_to "Log in", new_session_path(resource_name) %>
3 | <% end -%> 4 | 5 | <%- if devise_mapping.registerable? && controller_name != 'registrations' %> 6 | <%= link_to "Sign up", new_registration_path(resource_name) %>
7 | <% end -%> 8 | 9 | <%- if devise_mapping.recoverable? && controller_name != 'passwords' && controller_name != 'registrations' %> 10 | <%= link_to "Forgot your password?", new_password_path(resource_name) %>
11 | <% end -%> 12 | 13 | <%- if devise_mapping.confirmable? && controller_name != 'confirmations' %> 14 | <%= link_to "Didn't receive confirmation instructions?", new_confirmation_path(resource_name) %>
15 | <% end -%> 16 | 17 | <%- if devise_mapping.lockable? && resource_class.unlock_strategy_enabled?(:email) && controller_name != 'unlocks' %> 18 | <%= link_to "Didn't receive unlock instructions?", new_unlock_path(resource_name) %>
19 | <% end -%> 20 | 21 | <%- if devise_mapping.omniauthable? %> 22 | <%- resource_class.omniauth_providers.each do |provider| %> 23 | <%= link_to "Sign in with #{OmniAuth::Utils.camelize(provider)}", omniauth_authorize_path(resource_name, provider) %>
24 | <% end -%> 25 | <% end -%> 26 | -------------------------------------------------------------------------------- /docs/branding.md: -------------------------------------------------------------------------------- 1 | # Branding 2 | 3 | We have designed a curated image for the project involving a logo, typography set, color palette and illustrations. 4 | 5 | ## Logo 6 | 7 | The app logo is the one you can see below these lines. We have both a PNG and a SVG version in our [GitHub repo](https://github.com/infusionvlc/ConexionFelina). 8 | 9 |
10 | 11 | ![Application logo](assets/logo.svg) 12 | 13 |
14 | 15 | ## Typography 16 | 17 | Our main typefaces used throughout the web application are: 18 | 19 | - Raleway: used for all titles and body content. 20 | - Zilla slab: used for special titles that need to bring users attention. 21 | 22 | ## Color palette 23 | 24 | ![Color palette](assets/colors.png) 25 | 26 | ## Covi 27 | 28 | Covi is the main character in the project. He's a super heroe that takes care of the city gardens and protects citizens - with his friends help - from plagues. 29 | 30 |
31 | 32 | ![Covi](assets/heroe.gif ':size=300') 33 | 34 |
35 | 36 | ## Illustrations 37 | 38 | There's a bunch of illustrations in our [GitHub repo](https://github.com/infusionvlc/ConexionFelina/public). 39 | 40 |
41 | 42 | ![Covi](assets/zen.gif ':size=300') 43 | 44 |
-------------------------------------------------------------------------------- /app/controllers/cats/build_controller.rb: -------------------------------------------------------------------------------- 1 | class Cats::BuildController < ApplicationController 2 | include Wicked::Wizard 3 | 4 | steps :add_basic_info, :add_origin, :add_abandoned_date, 5 | :add_colony, :has_been_to_vet, :add_vet_info, :add_illnesses, 6 | :add_bio, :finish 7 | 8 | def show 9 | @cat = Cat.find(params[:cat_id]) 10 | render_wizard 11 | end 12 | 13 | 14 | def update 15 | @cat = Cat.find(params[:cat_id]) 16 | params[:cat][:saved_state] = step.to_s 17 | params[:cat][:saved_state] = 'active' if step == steps.last 18 | @cat.update_attributes(build_params) 19 | 20 | if params[:commit] == 'repeat' 21 | redirect_to new_cat_path 22 | elsif params[:commit] == 'profile' 23 | redirect_to @cat 24 | else 25 | render_wizard @cat 26 | end 27 | end 28 | 29 | 30 | def create 31 | @cat = Cat.create 32 | redirect_to wizard_path(steps.first, :cat_id => @cat.id) 33 | end 34 | 35 | private 36 | def build_params 37 | params.require(:cat).permit(:name, :gender, :birthday_date, :abandoned_date, :bio, :saved_state, :colony_id, :document, :sterilized, 38 | sufferings_attributes: [:id, :illness_id, :cat_id, :diagnosis_date, :notes, :chronic, :status, :_destroy]) 39 | end 40 | end -------------------------------------------------------------------------------- /app/views/cats/build/add_illnesses.html.erb: -------------------------------------------------------------------------------- 1 |

Illnesses

2 | 3 |
4 | <%= form_for(@cat, :url => wizard_path, :method => :put) do |f| %> 5 | <%= f.fields_for :sufferings do |f| %> 6 |
7 |
8 | <%= f.label :status %>
9 | <%= f.select :status, Suffering.statuses.keys.map { |w| [w.humanize, w] } %>
10 | 11 | <%= f.hidden_field :cat_id, params[:cat_id] %> 12 | 13 | <%= f.label "Illness" %>
14 | <%= f.collection_select(:illness_id, Illness.all, :id, :name ) %>
15 | 16 | <%= f.check_box :chronic %> 17 | <%= f.label :chronic %> 18 | 19 | <%= f.label :diagnosis_date %>
20 | <%= f.date_field :diagnosis_date, class: 'form-control' %> 21 | 22 | <%= f.label :notes %>
23 | <%= f.text_area :notes, class:'form-control' %>
24 | 25 | <%= f.check_box :_destroy %> 26 | <%= f.label :_destroy, "Remove" %> 27 |
28 |
29 | <% end %> 30 | 33 | <%= f.submit 'Siguiente', :class => 'btn btn-primary' %> 34 | <% end %> 35 |
36 | -------------------------------------------------------------------------------- /app/controllers/turns_controller.rb: -------------------------------------------------------------------------------- 1 | class TurnsController < ApplicationController 2 | def index 3 | @assignment_id = params[:assignment_id] 4 | @colony_id = params[:colony_id] 5 | @turns = Turn.where(assignment_id: @assignment_id) 6 | end 7 | 8 | def new 9 | @turn = Turn.new 10 | authorize @turn 11 | end 12 | 13 | def create 14 | @turn = Turn.new(turn_params) 15 | @turn.assignment_id = params[:assignment_id] 16 | authorize @turn 17 | @turn.save 18 | redirect_to assignments_path(colony_id: params[:colony_id]) 19 | end 20 | 21 | def edit 22 | @turn = Turn.find(params[:id]) 23 | authorize @turn 24 | end 25 | 26 | def update 27 | @turn = Turn.find(params[:id]) 28 | authorize @turn 29 | @turn.update(turn_params) 30 | redirect_to assignments_path(colony_id: params[:colony_id]) 31 | end 32 | 33 | def destroy 34 | @turn = Turn.find(params[:id]) 35 | @turn.destroy 36 | redirect_to(assignments_path(colony_id: params[:colony_id])) 37 | end 38 | 39 | private 40 | 41 | def user_not_autorized 42 | flash[:alert] = 'You are not autorized to perform this action' 43 | redirect_to turns_path 44 | end 45 | 46 | def turn_params 47 | params.require(:turn).permit(:start_date, :end_date, :assignment_id) 48 | end 49 | end 50 | -------------------------------------------------------------------------------- /spec/validators/sponsor_validator_spec.rb: -------------------------------------------------------------------------------- 1 | require "rails_helper" 2 | 3 | RSpec.describe SponsorValidator do 4 | def mock_relationships(sponsor) 5 | sponsor.cat = mock_model("Cat") 6 | sponsor.user = mock_model("User") 7 | end 8 | 9 | context "given a sponsor with its last payment date earlier than today" do 10 | it "must be valid" do 11 | valid_sponsor = Sponsor.new(amount: 1, renovate: true, start_date: Date.yesterday, last_payment_date: Date.yesterday) 12 | mock_relationships(valid_sponsor) 13 | 14 | expect(valid_sponsor).to be_valid 15 | end 16 | end 17 | 18 | context "given a sponsor with its last payment date equal to today" do 19 | it "must be valid" do 20 | valid_sponsor = Sponsor.new(amount: 1, renovate: true, start_date: Date.yesterday, last_payment_date: Date.today) 21 | mock_relationships(valid_sponsor) 22 | 23 | expect(valid_sponsor).to be_valid 24 | end 25 | end 26 | 27 | context "given a sponsor with its last payment date later than today" do 28 | it "must be invalid" do 29 | invalid_sponsor = Sponsor.new(amount: 1, renovate: true, start_date: Date.yesterday, last_payment_date: Date.tomorrow) 30 | mock_relationships(invalid_sponsor) 31 | 32 | expect(invalid_sponsor).to_not be_valid 33 | end 34 | end 35 | end 36 | -------------------------------------------------------------------------------- /app/views/cats/show.html.erb: -------------------------------------------------------------------------------- 1 | <%= image_tag(@cat.avatar) if !@cat.avatar.nil? %> 2 |

<%= @cat.name %>

3 |
4 | <%= @cat.bio %>
5 | birthday: <%= @cat.birthday_date %>
6 | gender: <%= @cat.gender %>
7 | sterilized: <%= @cat.sterilized %>
8 | <% if !(@cat.abandoned_date.nil?) %> 9 | abandoned: <%= @cat.abandoned_date %>
10 | <% end %> 11 | <% if !(@cat.document.nil?) %> 12 | document: <%= @cat.document %>
13 | <% end %> 14 | <% if policy(@cat).volunteer_or_admin? %> 15 | <%= link_to "List of sufferings", sufferings_path(:cat_id => @cat.id) %>
16 | <%= link_to "New suffering", new_suffering_path(:cat_id => @cat.id) %>
17 | <%= link_to "Delete", cat_path(:id => @cat.id), :method => :delete, data: { confirm: 'Are you sure?' } %>
18 | <% end %> 19 | 20 | <% if policy(@cat).adopt? %> 21 | <%= link_to "Adopt", adopt_cat_path(id: @cat.id) %>
22 | <% end %> 23 | 24 | <% if policy(@cat).sponsor? %> 25 | <%= link_to "Sponsor", new_sponsor_cat_path(id: @cat.id) %>
26 | <% end %> 27 | 28 | <% if policy(@cat).edit? %> 29 | <%= link_to "Edit", cat_path(:id => @cat.id), :method => :edit %>
30 | <% end %> 31 | 32 | <% if policy(@cat).destroy? %> 33 | <%= link_to "Delete", cat_path(:id => @cat.id), :method => :delete, data: { confirm: 'Are you sure?' } %>
34 | <% end %> 35 | -------------------------------------------------------------------------------- /app/views/devise/registrations/new.html.erb: -------------------------------------------------------------------------------- 1 |

Sign up

2 | 3 | <%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %> 4 | <%= devise_error_messages! %> 5 | 6 |
7 | <%= f.label :email %>
8 | <%= f.email_field :email, autofocus: true, autocomplete: "email" %> 9 |
10 |
11 | <%= f.label :username %>
12 | <%= f.text_field :username %> 13 |
14 |
15 | <%= f.label :role %>
16 | <%= f.select(:role, [['Admin', :admin], ['Volunteer', :volunteer], ['Basic', :basic]], :prompt => 'Select') %> 17 | 18 |
19 |
20 | <%= f.label :purrs %>
21 | <%= f.number_field :purrs %> 22 |
23 | 24 |
25 | <%= f.label :password %> 26 | <% if @minimum_password_length %> 27 | (<%= @minimum_password_length %> characters minimum) 28 | <% end %>
29 | <%= f.password_field :password, autocomplete: "off" %> 30 |
31 | 32 |
33 | <%= f.label :password_confirmation %>
34 | <%= f.password_field :password_confirmation, autocomplete: "off" %> 35 |
36 | 37 |
38 | <%= f.submit "Sign up" %> 39 |
40 | <% end %> 41 | 42 | <%= render "devise/shared/links" %> 43 | -------------------------------------------------------------------------------- /app/controllers/illnesses_controller.rb: -------------------------------------------------------------------------------- 1 | class IllnessesController < ApplicationController 2 | 3 | rescue_from Pundit::NotAuthorizedError, with: :user_not_authorized 4 | 5 | def index 6 | @illnesses = Illness.all 7 | end 8 | 9 | def new 10 | @illness = Illness.new 11 | authorize @illness 12 | end 13 | 14 | def create 15 | @illness = Illness.new(illness_params) 16 | authorize @illness 17 | @illness.save 18 | redirect_to( illnesses_path ) 19 | end 20 | 21 | def edit 22 | @illness = Illness.find( params[ :id ]) 23 | authorize @illness 24 | end 25 | 26 | def update 27 | @illness = Illness.find( params[ :id ]) 28 | authorize @illness 29 | @illness.update( illness_params ) 30 | redirect_to (illness_path( params[ :id ] )) 31 | end 32 | 33 | def show 34 | @illness = Illness.find( params[ :id ]) 35 | end 36 | 37 | def destroy 38 | @illness = Illness.find( params[ :id ]) 39 | authorize @illness 40 | @illness.destroy 41 | redirect_to( illnesses_path ) 42 | end 43 | 44 | private 45 | 46 | def illness_params 47 | params.require(:illness).permit(:name, :description, :priority, :treatment) 48 | end 49 | 50 | def user_not_authorized 51 | flash[:alert] = "You are not autorized to perform this action" 52 | redirect_to illnesses_path 53 | end 54 | end 55 | -------------------------------------------------------------------------------- /config/secrets.yml: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Your secret key is used for verifying the integrity of signed cookies. 4 | # If you change this key, all old signed cookies will become invalid! 5 | 6 | # Make sure the secret is at least 30 characters and all random, 7 | # no regular words or you'll be exposed to dictionary attacks. 8 | # You can use `rails secret` to generate a secure secret key. 9 | 10 | # Make sure the secrets in this file are kept private 11 | # if you're sharing your code publicly. 12 | 13 | # Shared secrets are available across all environments. 14 | 15 | # shared: 16 | # api_key: a1B2c3D4e5F6 17 | 18 | # Environmental secrets are only available for that specific environment. 19 | 20 | development: 21 | secret_key_base: d7558d2d36b58998e08e48536d16e0c6b8d9ae1d2f272ed4368802272e6b65fa18d7c66ecd103f400c64b2cb5f713b29d6aa05ea99df67da665fb92dda9907c4 22 | 23 | test: 24 | secret_key_base: 1227f3ff8413530f5b06cb1f6ed75eaa9fa4225835865e28aed14034ac1eb6a0aa9c7674c263bcd9635985e7e6ab60c7b52c45c624b97201da6b9b47751c8142 25 | 26 | # Do not keep production secrets in the unencrypted secrets file. 27 | # Instead, either read values from the environment. 28 | # Or, use `bin/rails secrets:setup` to configure encrypted secrets 29 | # and move the `production:` environment over there. 30 | 31 | production: 32 | secret_key_base: <%= ENV["SECRET_KEY_BASE"] %> 33 | -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Covi Project 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |
14 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /app/views/pages/work.html.erb: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |

<%= t 'landing.work.intro' %>

5 | 6 |
7 |
8 |
9 |

<%= t 'landing.work.labor' %>

10 | 11 |
12 |
13 |
14 |

<%= t 'landing.work.sterilize.title' %>

15 |

<%= t 'landing.work.sterilize.paragraph1' %>

16 |

<%= t 'landing.work.sterilize.paragraph2' %>

17 |
18 | 19 |
20 | 21 |
22 |
23 |

<%= t 'landing.work.coexist.title' %>

24 |

<%= t 'landing.work.coexist.paragraph1' %>

25 |

<%= t 'landing.work.coexist.paragraph2' %>

26 |
27 | 28 |
29 | 30 |
31 |
32 |

<%= t 'landing.work.care.title' %>

33 |

<%= t 'landing.work.care.paragraph1' %>

34 |
35 | 36 |
37 |
38 |
39 |
40 | -------------------------------------------------------------------------------- /app/views/pages/league.html.erb: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 |
5 | 6 |

7 | <%= t 'landing.league.intro' %> 8 |

9 |

10 | <%= t 'landing.league.subtitle'%> 11 |

12 |
13 |
14 | 15 | 16 |
17 |
18 | 19 | 20 |
21 |
22 | 23 |

24 | Covi 25 |

26 |
27 |
28 | 29 |

30 | Covi 31 |

32 |
33 |
34 | 35 |

36 | Covi 37 |

38 |
39 |
40 | 41 |

42 | Covi 43 |

44 |
45 |
46 | 47 |

48 | Covi 49 |

50 |
51 |
52 | 53 |

54 | Covi 55 |

56 |
57 |
58 |
-------------------------------------------------------------------------------- /app/controllers/sufferings_controller.rb: -------------------------------------------------------------------------------- 1 | class SufferingsController < ApplicationController 2 | def show 3 | suffering_id = params[:id] 4 | @suffering = Suffering.find(suffering_id) 5 | authorize @suffering 6 | end 7 | 8 | def index 9 | cat_id = params[:cat_id] 10 | @sufferings = Suffering.where(cat_id: cat_id) 11 | end 12 | 13 | def new 14 | @suffering = Suffering.new 15 | authorize @suffering 16 | end 17 | 18 | def create 19 | @suffering = Suffering.new(suffering_params) 20 | @suffering.cat_id = params[:cat_id] 21 | authorize @suffering 22 | @suffering.save 23 | redirect_to(cats_path) 24 | end 25 | 26 | def edit 27 | @suffering = Suffering.find(params[:id]) 28 | authorize @suffering 29 | end 30 | 31 | def update 32 | @suffering = Suffering.find(params[:id]) 33 | authorize @suffering 34 | @suffering.update(suffering_params) 35 | redirect_to suffering_path(@suffering) 36 | end 37 | 38 | def destroy 39 | @suffering = Suffering.find(params[:id]) 40 | authorize @suffering 41 | @suffering.destroy 42 | redirect_to sufferings_path(:cat_id => @suffering.cat_id) 43 | end 44 | 45 | private 46 | 47 | def user_not_autorized 48 | flash[:alert] = "You are not autorized to perform this action" 49 | redirect_to suffering_path 50 | end 51 | 52 | def suffering_params 53 | params.require(:suffering).permit(:diagnosis_date, :notes, :chronic, :status, :cat_id, :illness_id) 54 | end 55 | end 56 | -------------------------------------------------------------------------------- /docs/i18n.md: -------------------------------------------------------------------------------- 1 | # Translations 2 | 3 | So you want to help us translate the app to another language? 4 | Here you'll find some advice :wink: 5 | 6 | ## How internationalization works in ruby on rails? 7 | 8 | RoR use I18n, is easy to configure, we just add the string in 9 | the .yml of the language. 10 | 11 | ## Where are the .yml of each language? 12 | 13 | The .yml of each language are in `config/locales/`, there can be added all 14 | the .yml as `[language_code].yml` you can see 15 | [here](https://es.wikipedia.org/wiki/ISO_639-1) the code of all the languages. 16 | 17 | ## How we organice the values of the .yml 18 | We encapsulate the values by HTML elements such as cats, users, sufferings etc. 19 | in the second level of the hierarchy. 20 | 21 | For example: 22 | ``` 23 | es: 24 | [...] 25 | cats: 26 | birthDate: 'Nacido aproximadamente el' 27 | gender: 'Género:' 28 | sterilized: 'Esterilizado:' 29 | abandonedDate: 'Abandonado aproximadamente el' 30 | document: 'Documento:' 31 | ``` 32 | 33 | ## How add the values to the HTML code. 34 | We just need to add a line like this in our HTML file 35 | `<%= I18n.t 'cats.sterilized'%>`, this line will show `Esterilizado:` 36 | 37 | ### Sources 38 | Our es.yml: https://github.com/infusionvlc/ConexionFelina/blob/master/config/locales/es.yml 39 | 40 | Example: https://github.com/infusionvlc/ConexionFelina/blob/master/app/views/cats/index.html.erb 41 | 42 | Language codes: https://es.wikipedia.org/wiki/ISO_639-1 43 | 44 | Source: http://guides.rubyonrails.org/i18n.html -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files for more about ignoring files. 2 | # 3 | # If you find yourself ignoring temporary files generated by your text editor 4 | # or operating system, you probably want to add a global ignore instead: 5 | # git config --global core.excludesfile '~/.gitignore_global' 6 | 7 | *.rbc 8 | capybara-*.html 9 | .rspec 10 | /log 11 | /tmp 12 | /db/*.sqlite3 13 | /db/*.sqlite3-journal 14 | /public/system 15 | /coverage/ 16 | /spec/tmp 17 | *.orig 18 | rerun.txt 19 | pickle-email-*.html 20 | 21 | # TODO Comment out this rule if you are OK with secrets being uploaded to the repo 22 | config/initializers/secret_token.rb 23 | config/master.key 24 | 25 | # Only include if you have production secrets in this file, which is no longer a Rails default 26 | # config/secrets.yml 27 | 28 | # dotenv 29 | # TODO Comment out this rule if environment variables can be committed 30 | .env 31 | 32 | ## Environment normalization: 33 | /.bundle 34 | /vendor/bundle 35 | 36 | # these should all be checked in to normalize the environment: 37 | Gemfile.lock, .ruby-version, .ruby-gemset 38 | 39 | # unless supporting rvm < 1.11.0 or doing something fancy, ignore this: 40 | .rvmrc 41 | 42 | # if using bower-rails ignore default bower_components path bower.json files 43 | /vendor/assets/bower_components 44 | *.bowerrc 45 | bower.json 46 | 47 | # Ignore pow environment settings 48 | .powenv 49 | 50 | # Ignore Byebug command history file. 51 | .byebug_history 52 | 53 | # Ignore node_modules 54 | node_modules/ 55 | 56 | # Ignore .vs 57 | .vs/ -------------------------------------------------------------------------------- /app/models/cat.rb: -------------------------------------------------------------------------------- 1 | class Cat < ApplicationRecord 2 | MAXIMUM_NAME_LENGTH = 20 3 | MAXIMUM_BIO_LENGTH = 512 4 | MINIMUM_BIRTH_DATE = Date.today 5 | 6 | enum gender: [:male, :female] 7 | enum sterilized: [:yes, :no] 8 | 9 | has_many :sufferings 10 | has_many :illnesses, through: :sufferings 11 | belongs_to :colony 12 | has_one :adoption 13 | has_many :sponsors 14 | has_many :users, through: :sponsors 15 | 16 | accepts_nested_attributes_for :sufferings, reject_if: :all_blank, allow_destroy: true 17 | 18 | validates :name, presence: true, :if => :active_or_basic_info? 19 | validate :birthday_date_must_be_in_the_past, :if => :active_or_basic_info? 20 | validates :name, length: { maximum: MAXIMUM_NAME_LENGTH }, :if => :active_or_basic_info? 21 | 22 | validates :bio, length: { maximum: MAXIMUM_BIO_LENGTH }, :if => :active_or_bio? 23 | 24 | validates :colony_id, presence: true, :if => :active_or_colony? 25 | 26 | 27 | def active? 28 | saved_state == 'active' 29 | end 30 | 31 | def active_or_basic_info? 32 | saved_state && (saved_state.include?('basic_info') || active?) 33 | end 34 | 35 | def active_or_bio? 36 | saved_state && (saved_state.include?('bio') || active?) 37 | end 38 | 39 | def active_or_colony? 40 | saved_state && ( saved_state.include?('colony') || active?) 41 | end 42 | 43 | 44 | def birthday_date_must_be_in_the_past 45 | if birthday_date != nil 46 | if birthday_date > Date.today 47 | errors.add(:expiration_date, "Birthdate must be in the past") 48 | end 49 | end 50 | end 51 | 52 | end 53 | -------------------------------------------------------------------------------- /app/views/devise/registrations/edit.html.erb: -------------------------------------------------------------------------------- 1 |

Edit <%= resource_name.to_s.humanize %>

2 | 3 | <%= form_for(resource, as: resource_name, url: registration_path(resource_name), html: { method: :put }) do |f| %> 4 | <%= devise_error_messages! %> 5 | 6 |
7 | <%= f.label :email %>
8 | <%= f.email_field :email, autofocus: true, autocomplete: "email" %> 9 |
10 | 11 | <% if devise_mapping.confirmable? && resource.pending_reconfirmation? %> 12 |
Currently waiting confirmation for: <%= resource.unconfirmed_email %>
13 | <% end %> 14 | 15 |
16 | <%= f.label :password %> (leave blank if you don't want to change it)
17 | <%= f.password_field :password, autocomplete: "off" %> 18 | <% if @minimum_password_length %> 19 |
20 | <%= @minimum_password_length %> characters minimum 21 | <% end %> 22 |
23 | 24 |
25 | <%= f.label :password_confirmation %>
26 | <%= f.password_field :password_confirmation, autocomplete: "off" %> 27 |
28 | 29 |
30 | <%= f.label :current_password %> (we need your current password to confirm your changes)
31 | <%= f.password_field :current_password, autocomplete: "off" %> 32 |
33 | 34 |
35 | <%= f.submit "Update" %> 36 |
37 | <% end %> 38 | 39 |

Cancel my account

40 | 41 |

Unhappy? <%= button_to "Cancel my account", registration_path(resource_name), data: { confirm: "Are you sure?" }, method: :delete %>

42 | 43 | <%= link_to "Back", :back %> 44 | -------------------------------------------------------------------------------- /docs/home.md: -------------------------------------------------------------------------------- 1 | # Covi Project 2 | 3 | Hey! :wave: Welcome to the **official Covi Project docs**. :books: 4 | 5 | This project aims to introduce people to the situation of cats from 6 | cat colonies 🐱❤️ 7 | 8 | This is an application to make easier the work of the volunteers who take care 9 | of street cats, built with all the contributions our collaborators have done 10 | with a lot of effort and with a lot of love. ❤️ 11 | 12 | We believe that diversity is a source of wealth in all areas and that is why 13 | we want to **welcome all people**, whatever their, gender, age, experience, 14 | origin, etc. 👱🧔🏽👨🌾👵 Therefore, everyone involved in the community must 15 | comply with our [code of conduct](www.infusionvlc.com/rules). 🖐️ 16 | 17 | ## How to Contribute 18 | 19 | Our team is made up of people with very different experiences: developer, 20 | designers and translators. Any help is always welcome and we're always 21 | looking for more people to participate in all our projects. 22 | 23 | You can [send us a message](mailto:hola@infusionvlc.com) and tell us a bit 24 | about yourself and what you want to help us out with. We will send you an 25 | invitation to our team's slack space. 26 | 27 | ## Open Collective 28 | 29 | Many thanks to all the sponsors and sponsors who contribute your bit to 30 | the community! You can also join and help us continue to make use of these projects. 31 | 32 | 33 | 34 | ![](https://camo.githubusercontent.com/71fd92823a37901ddb65da615f13fea9f3ae9dbf/68747470733a2f2f6f70656e636f6c6c6563746976652e636f6d2f696e667573696f6e766c632f6261636b6572732e7376673f77696474683d383930) 35 | 36 | -------------------------------------------------------------------------------- /docs/installation.md: -------------------------------------------------------------------------------- 1 | # Setting up the development environment 2 | 3 | Hey! :wave: We are so glad you want to help us shape a better future for 4 | street cats. Here you'll find some notes on how to install the web application 5 | on your computer. Let's get started! :rocket: 6 | 7 | ## Installing Ruby on Rails 8 | Please, follow along the instructions for yor OS (**INSTALL POSTGRESQL**) 9 | 10 | https://gorails.com/setup/ 11 | 12 | ## Cloning the repo locally 13 | Create a fork of this repo and clone it into your PC: 14 | `git clone https://github.com/your_user/ConexionFelina.git` 15 | 16 | ## Installing bundled gems 17 | Run `bundle install` inside the 'ConexionFelina' app directory. 18 | 19 | ## First run 20 | 1. `rails db:create` 21 | 2. `rails db:migrate` 22 | 3. `rails db:seed` 23 | 24 | If you want to migrate and populate the test database too you should 25 | add `RAILS_ENV=TEST` at the end of the 2º and 3º commands and execute them. 26 | 27 | `rails s` 28 | 29 | 30 | ## Configuring postgresql on linux (ubuntu) 31 | 1. Run `sudo -u postgres createuser --interactive` 32 | Use as username your OS account name 33 | Type "y" to be superuser 34 | 2. Run `sudo -u [your OS account name] createdb conexion_felina_test` 35 | 36 | ## Configuring postgreSQL on Mac OS 37 | 1. `createuser -s -r postgres` 38 | 39 | ## Front-end development Environment 40 | 41 | ### Installing the required tools 42 | - To install Node.js 43 | 44 | `brew install node` 45 | 46 | - To install Yarn 47 | 48 | `brew install yarn` 49 | 50 | - To install Storybook and other dependencies 51 | 52 | `npm install` 53 | 54 | `yarn install` 55 | 56 | Please, checkout our [conventions guidelines](conventions.md) to know more 57 | about our code quality specs and how to run tests. -------------------------------------------------------------------------------- /app/controllers/treatment_entries_controller.rb: -------------------------------------------------------------------------------- 1 | class TreatmentEntriesController < ApplicationController 2 | def index 3 | suffering_id = params[:suffering_id] 4 | @treatment_entries = TreatmentEntry.where(suffering_id: suffering_id) 5 | end 6 | 7 | def show 8 | treatment_entry_id = params[:id] 9 | @treatment_entry = TreatmentEntry.find(treatment_entry_id) 10 | authorize @treatment_entry 11 | end 12 | 13 | def new 14 | @treatment_entry = TreatmentEntry.new 15 | authorize @treatment_entry 16 | end 17 | 18 | def create 19 | @treatment_entry = TreatmentEntry.new(treatment_entry_params) 20 | @treatment_entry.suffering_id = params[:suffering_id] 21 | authorize @treatment_entry 22 | @treatment_entry.save 23 | redirect_to suffering_path(@treatment_entry.suffering_id) 24 | end 25 | 26 | def edit 27 | @treatment_entry = TreatmentEntry.find(params[:id]) 28 | authorize @treatment_entry 29 | end 30 | 31 | def update 32 | @treatment_entry = TreatmentEntry.find(params[:id]) 33 | authorize @treatment_entry 34 | @treatment_entry.update(treatment_entry_params) 35 | redirect_to treatment_entries_path(suffering_id: @treatment_entry.suffering_id) 36 | end 37 | 38 | def destroy 39 | @treatment_entry = TreatmentEntry.find(params[:id]) 40 | authorize @treatment_entry 41 | @treatment_entry.destroy 42 | redirect_to treatment_entries_path(suffering_id: @treatment_entry.suffering_id) 43 | end 44 | 45 | private 46 | 47 | def user_not_autorized 48 | flash[:alert] = 'You are not autorized to perform this action' 49 | redirect_to treatment_entry_path 50 | end 51 | 52 | def treatment_entry_params 53 | params.require(:treatment_entry).permit(:date, :treatment, :notes, :suffering_id) 54 | end 55 | end 56 | -------------------------------------------------------------------------------- /docs/learning.md: -------------------------------------------------------------------------------- 1 | # Learning Resources 2 | 3 | Here you can find some useful resources for learning about coding, team-work and testing. 4 | Feel free to open up a PR with your additions :wink: 5 | 6 | ## Git 7 | * [Git handbook](https://guides.github.com/introduction/git-handbook/) 8 | * [Learn Git branching](https://learngitbranching.js.org/) 9 | * [Git cheatsheets](https://services.github.com/on-demand/resources/cheatsheets/) 10 | 11 | ## Team building & communities 12 | * [10 ways to improve your pairing experience](https://www.thoughtworks.com/insights/blog/10-ways-improve-your-pairing-experience) 13 | * [10 commandments of code reviews](https://techbeacon.com/10-commandments-navigating-code-reviews) 14 | 15 | ## Translations 16 | * [Rails internationalization guides](https://guides.rubyonrails.org/i18n.html) 17 | 18 | ## Software Engineering 19 | * [Refactoring by Source Making](https://sourcemaking.com/refactoring) 20 | * [Design patterns by Source Making](https://sourcemaking.com/design_patterns) 21 | * [Clean Code exercises by Upcase](https://thoughtbot.com/upcase/clean-code) 22 | 23 | ## Back-end: Ruby on Rails 24 | * [Rails guides](https://guides.rubyonrails.org/index.html) 25 | * [HTTP, MVC and routes](https://medium.com/the-renaissance-developer/ruby-on-rails-http-mvc-and-routes-f02215a46a84) 26 | * [Rails testing](https://hackernoon.com/your-guide-to-testing-in-ruby-on-rails-5-c8bd122e38ad) 27 | * [Rspec best practices](https://jacopretorius.net/2013/11/rspec-best-practices.html) 28 | * [Better Specs](http://www.betterspecs.org/) 29 | 30 | ## Front-end: React, JS 31 | * [Getting started with React](https://reactjs.org/docs/getting-started.html) 32 | * [Storybook introduction](https://storybook.js.org/basics/introduction/) 33 | * [W3Schools guide on Javascript](https://www.w3schools.com/js/) 34 | -------------------------------------------------------------------------------- /.idea/ConexionFelina.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /public/500.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | We're sorry, but something went wrong (500) 5 | 6 | 55 | 56 | 57 | 58 | 59 |
60 |
61 |

We're sorry, but something went wrong.

62 |
63 |

If you are the application owner check the logs for more information.

64 |
65 | 66 | 67 | -------------------------------------------------------------------------------- /config/environments/test.rb: -------------------------------------------------------------------------------- 1 | Rails.application.configure do 2 | # Settings specified here will take precedence over those in config/application.rb. 3 | 4 | # The test environment is used exclusively to run your application's 5 | # test suite. You never need to work with it otherwise. Remember that 6 | # your test database is "scratch space" for the test suite and is wiped 7 | # and recreated between test runs. Don't rely on the data there! 8 | config.cache_classes = true 9 | 10 | # Do not eager load code on boot. This avoids loading your whole application 11 | # just for the purpose of running a single test. If you are using a tool that 12 | # preloads Rails for running tests, you may have to set it to true. 13 | config.eager_load = false 14 | 15 | # Configure public file server for tests with Cache-Control for performance. 16 | config.public_file_server.enabled = true 17 | config.public_file_server.headers = { 18 | 'Cache-Control' => "public, max-age=#{1.hour.seconds.to_i}" 19 | } 20 | 21 | # Show full error reports and disable caching. 22 | config.consider_all_requests_local = true 23 | config.action_controller.perform_caching = false 24 | 25 | # Raise exceptions instead of rendering exception templates. 26 | config.action_dispatch.show_exceptions = false 27 | 28 | # Disable request forgery protection in test environment. 29 | config.action_controller.allow_forgery_protection = false 30 | config.action_mailer.perform_caching = false 31 | 32 | # Tell Action Mailer not to deliver emails to the real world. 33 | # The :test delivery method accumulates sent emails in the 34 | # ActionMailer::Base.deliveries array. 35 | config.action_mailer.delivery_method = :test 36 | 37 | # Print deprecation notices to the stderr. 38 | config.active_support.deprecation = :stderr 39 | 40 | # Raises error for missing translations 41 | # config.action_view.raise_on_missing_translations = true 42 | end 43 | -------------------------------------------------------------------------------- /db/migrate/20180620160551_add_devise_to_users.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | class AddDeviseToUsers < ActiveRecord::Migration[5.1] 4 | def self.up 5 | change_table :users do |t| 6 | ## Database authenticatable 7 | t.string :email, null: false, default: "" 8 | t.string :encrypted_password, null: false, default: "" 9 | 10 | ## Recoverable 11 | t.string :reset_password_token 12 | t.datetime :reset_password_sent_at 13 | 14 | ## Rememberable 15 | t.datetime :remember_created_at 16 | 17 | ## Trackable 18 | t.integer :sign_in_count, default: 0, null: false 19 | t.datetime :current_sign_in_at 20 | t.datetime :last_sign_in_at 21 | t.inet :current_sign_in_ip 22 | t.inet :last_sign_in_ip 23 | 24 | ## Confirmable 25 | # t.string :confirmation_token 26 | # t.datetime :confirmed_at 27 | # t.datetime :confirmation_sent_at 28 | # t.string :unconfirmed_email # Only if using reconfirmable 29 | 30 | ## Lockable 31 | # t.integer :failed_attempts, default: 0, null: false # Only if lock strategy is :failed_attempts 32 | # t.string :unlock_token # Only if unlock strategy is :email or :both 33 | # t.datetime :locked_at 34 | 35 | 36 | # Uncomment below if timestamps were not included in your original model. 37 | # t.timestamps null: false 38 | end 39 | 40 | add_index :users, :email, unique: true 41 | add_index :users, :reset_password_token, unique: true 42 | # add_index :users, :confirmation_token, unique: true 43 | # add_index :users, :unlock_token, unique: true 44 | end 45 | 46 | def self.down 47 | # By default, we don't want to make any assumption about how to roll back a migration when your 48 | # model already existed. Please edit below which fields you would like to remove in this migration. 49 | raise ActiveRecord::IrreversibleMigration 50 | end 51 | end 52 | -------------------------------------------------------------------------------- /public/422.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | The change you wanted was rejected (422) 5 | 6 | 55 | 56 | 57 | 58 | 59 |
60 |
61 |

The change you wanted was rejected.

62 |

Maybe you tried to change something you didn't have access to.

63 |
64 |

If you are the application owner check the logs for more information.

65 |
66 | 67 | 68 | -------------------------------------------------------------------------------- /public/404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | The page you were looking for doesn't exist (404) 5 | 6 | 55 | 56 | 57 | 58 | 59 |
60 |
61 |

The page you were looking for doesn't exist.

62 |

You may have mistyped the address or the page may have moved.

63 |
64 |

If you are the application owner check the logs for more information.

65 |
66 | 67 | 68 | -------------------------------------------------------------------------------- /config/favicon.json: -------------------------------------------------------------------------------- 1 | 2 | 3 | { 4 | "master_picture": "public/logo.png", 5 | "favicon_design": { 6 | "ios": { 7 | "picture_aspect": "background_and_margin", 8 | "background_color": "#ffffff", 9 | "margin": "14%", 10 | "assets": { 11 | "ios6_and_prior_icons": false, 12 | "ios7_and_later_icons": false, 13 | "precomposed_icons": false, 14 | "declare_only_default_icon": true 15 | } 16 | }, 17 | "desktop_browser": [ 18 | 19 | ], 20 | "windows": { 21 | "picture_aspect": "no_change", 22 | "background_color": "#2d89ef", 23 | "on_conflict": "override", 24 | "assets": { 25 | "windows_80_ie_10_tile": false, 26 | "windows_10_ie_11_edge_tiles": { 27 | "small": false, 28 | "medium": true, 29 | "big": false, 30 | "rectangle": false 31 | } 32 | } 33 | }, 34 | "android_chrome": { 35 | "picture_aspect": "no_change", 36 | "theme_color": "#ffffff", 37 | "manifest": { 38 | "display": "standalone", 39 | "orientation": "not_set", 40 | "on_conflict": "override", 41 | "declared": true 42 | }, 43 | "assets": { 44 | "legacy_icon": false, 45 | "low_resolution_icons": false 46 | } 47 | }, 48 | "safari_pinned_tab": { 49 | "picture_aspect": "black_and_white", 50 | "threshold": 58.59375, 51 | "theme_color": "#5bbad5" 52 | } 53 | }, 54 | "settings": { 55 | "scaling_algorithm": "Mitchell", 56 | "error_on_image_too_small": false, 57 | "readme_file": false, 58 | "html_code_file": false, 59 | "use_path_as_is": false 60 | } 61 | } 62 | 63 | -------------------------------------------------------------------------------- /app/controllers/cats_controller.rb: -------------------------------------------------------------------------------- 1 | class CatsController < ApplicationController 2 | def show 3 | cat_id = params[:id] 4 | @cat = Cat.find(cat_id) 5 | end 6 | 7 | def index 8 | @cats = Cat.all.where(saved_state: 'active') 9 | end 10 | 11 | def new 12 | @cat = Cat.new 13 | authorize @cat 14 | @cat.save 15 | redirect_to cat_build_path(:add_basic_info, cat_id: @cat.id) 16 | end 17 | 18 | def create 19 | @cat = Cat.create(cat_params) 20 | authorize @cat 21 | @cat.save 22 | redirect_to cat_path(@cat) 23 | end 24 | 25 | def edit 26 | @cat = Cat.find(params[:id]) 27 | authorize @cat 28 | end 29 | 30 | def update 31 | @cat = Cat.find(params[:id]) 32 | authorize @cat 33 | @cat.update(cat_params) 34 | redirect_to cat_path(@cat) 35 | end 36 | 37 | def destroy 38 | @cat = Cat.find(params[:id]) 39 | authorize @cat 40 | @cat.destroy 41 | redirect_to cats_path 42 | end 43 | 44 | def adopt 45 | @cat = Cat.find(params[:id]) 46 | authorize @cat 47 | Adoption.create(cat_id: @cat.id, user_id: current_user.id) 48 | end 49 | 50 | def new_sponsor 51 | @cat = Cat.find(params[:id]) 52 | authorize @cat 53 | end 54 | 55 | def sponsor 56 | cat = Cat.find(params[:id]) 57 | renovate = params[:renovate] || false 58 | 59 | authorize cat 60 | 61 | Sponsor.create(amount: params[:amount], renovate: renovate, 62 | last_payment_date: Date.today, start_date: Date.today, user: current_user, cat: cat) 63 | 64 | redirect_to cats_path 65 | end 66 | 67 | private 68 | 69 | def cat_params 70 | params.require(:cat).permit(:name, :bio, :birthday_date, :gender, 71 | :sterilized, :abandoned_date, :document, :colony_id, :saved_state, 72 | sufferings_attributes: [:id, :illness_id, :cat_id, :diagnosis_date, :notes, :chronic, :status, :_destroy]) 73 | end 74 | 75 | def user_not_autorized 76 | flash[:alert] = "You are not autorized to perform this action" 77 | redirect_to cats_path 78 | end 79 | end 80 | -------------------------------------------------------------------------------- /public/top.svg: -------------------------------------------------------------------------------- 1 | 2 | image/svg+xml -------------------------------------------------------------------------------- /app/views/layouts/pages.html.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Conexión Felina 5 | <%= csrf_meta_tags %> 6 | 7 | 8 | <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %> 9 | <%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %> 10 | 11 | 12 | 13 | 14 | 15 | 42 | <%= yield %> 43 | 47 | 48 | -------------------------------------------------------------------------------- /config/environments/development.rb: -------------------------------------------------------------------------------- 1 | Rails.application.configure do 2 | # Settings specified here will take precedence over those in config/application.rb. 3 | 4 | # In the development environment your application's code is reloaded on 5 | # every request. This slows down response time but is perfect for development 6 | # since you don't have to restart the web server when you make code changes. 7 | config.cache_classes = false 8 | 9 | # Do not eager load code on boot. 10 | config.eager_load = false 11 | 12 | # Show full error reports. 13 | config.consider_all_requests_local = true 14 | 15 | # Enable/disable caching. By default caching is disabled. 16 | if Rails.root.join('tmp/caching-dev.txt').exist? 17 | config.action_controller.perform_caching = true 18 | 19 | config.cache_store = :memory_store 20 | config.public_file_server.headers = { 21 | 'Cache-Control' => "public, max-age=#{2.days.seconds.to_i}" 22 | } 23 | else 24 | config.action_controller.perform_caching = false 25 | 26 | config.cache_store = :null_store 27 | end 28 | 29 | # Don't care if the mailer can't send. 30 | config.action_mailer.raise_delivery_errors = false 31 | 32 | config.action_mailer.perform_caching = false 33 | 34 | # Print deprecation notices to the Rails logger. 35 | config.active_support.deprecation = :log 36 | 37 | # Raise an error on page load if there are pending migrations. 38 | config.active_record.migration_error = :page_load 39 | 40 | # Debug mode disables concatenation and preprocessing of assets. 41 | # This option may cause significant delays in view rendering with a large 42 | # number of complex assets. 43 | config.assets.debug = true 44 | 45 | # Suppress logger output for asset requests. 46 | config.assets.quiet = true 47 | 48 | # Raises error for missing translations 49 | # config.action_view.raise_on_missing_translations = true 50 | 51 | config.action_mailer.default_url_options = { host: 'localhost', port: 3000 } 52 | 53 | # Use an evented file watcher to asynchronously detect changes in source code, 54 | # routes, locales, etc. This feature depends on the listen gem. 55 | # config.file_watcher = ActiveSupport::EventedFileUpdateChecker 56 | end 57 | -------------------------------------------------------------------------------- /spec/validators/treatment_entry_validator_spec.rb: -------------------------------------------------------------------------------- 1 | require "rails_helper" 2 | 3 | RSpec.describe TreatmentEntryValidator do 4 | def mock_relationships(treatment_entry) 5 | treatment_entry.suffering = mock_model("Suffering") 6 | end 7 | 8 | context "given a suffering with its last date earlier " do 9 | it "must be valid" do 10 | valid_treatment_entry = TreatmentEntry.new(date: Date.new(2001, 2, 3), treatment: 1) 11 | mock_relationships(valid_treatment_entry) 12 | 13 | expect(valid_treatment_entry).to be_valid 14 | end 15 | end 16 | 17 | context "given a date later than today or today" do 18 | it "must be invalid" do 19 | invalid_treatment_entry = TreatmentEntry.new(date: Date.tomorrow, treatment: 1) 20 | mock_relationships(invalid_treatment_entry) 21 | 22 | expect(invalid_treatment_entry).to_not be_valid 23 | end 24 | end 25 | 26 | context "given a notes with an amount bigger than 1024 " do 27 | it "must be invalid" do 28 | invalid_treatment_entry = TreatmentEntry.new(date: Date.yesterday, treatment: 1, notes: "morbi tristique senectus et netus et malesuada fames ac turpis egestas integer eget aliquet nibh praesent tristique magna sit amet purus gravida quis blandit turpis cursus in hac habitasse platea dictumst quisque sagittis purus sit amet volutpat consequat mauris nunc congue nisi vitae suscipit tellus mauris a diam maecenas sed enim ut sem viverra aliquet eget sit amet tellus cras adipiscing enim eu turpis egestas pretium aenean pharetra magna ac placerat vestibulum lectus mauris ultrices eros in cursus turpis massa tincidunt dui ut ornare lectus sit amet est placerat in egestas erat imperdiet sed euismod nisi porta lorem mollis aliquam ut porttitor leo a diam sollicitudin tempor id eu nisl nunc mi ipsum faucibus vitae aliquet nec ullamcorper sit amet risus nullam eget felis eget nunc lobortis mattis aliquam faucibus purus in massa tempor nec feugiat nisl pretium fusce id velit ut tortor pretium viverra suspendisse potenti nullam ac tortor vitae purus faucibus ornare suspendisse sed nisi lacus sed viverra tellus in hac habitasse platea dictumst") 29 | mock_relationships(invalid_treatment_entry) 30 | 31 | expect(invalid_treatment_entry).to_not be_valid 32 | end 33 | end 34 | end 35 | -------------------------------------------------------------------------------- /app/views/cats/edit.html.erb: -------------------------------------------------------------------------------- 1 | 2 |

Edit <%= @cat.name %>

3 | <%= form_for(@cat) do |f| %> 4 |
5 | <%= f.label :bio %>
6 | <%= f.text_area :bio%> 7 |
8 |
9 | <%= f.label :birthday_date %>
10 | <%= f.date_field :birthday_date %> 11 |
12 |
13 | <%= f.label :gender %>
14 | <%= f.select(:gender, [['Male', :male], ['Female', :female]], :prompt => 'Select') %> 15 |
16 |
17 | <%= f.label :sterilized %>
18 | <%= f.select(:sterilized, [['Yes', :yes], ['No', :no]], :prompt => 'Select') %> 19 |
20 |
21 | <%= f.label :abandoned_date %>
22 | <%= f.date_field :abandoned_date %> 23 |
24 |
25 | <%= f.label :document %>
26 | <%= f.text_field :document %> 27 |
28 |
29 | <%= f.label :colony_id %>
30 | <%= f.select(:colony_id, Colony.all.collect {|u| [u.name, u.id]}, :prompt => 'Select') %> 31 |
32 |
33 | <%= f.fields_for :sufferings do |ff| %> 34 |
35 |
36 | <%= ff.label :status %>
37 | <%= ff.select :status, Suffering.statuses.keys.map { |w| [w.humanize, w] } %>
38 | 39 | <%= ff.hidden_field :cat_id, params[:cat_id] %> 40 | 41 | <%= ff.label "Illness" %>
42 | <%= ff.collection_select(:illness_id, Illness.all, :id, :name ) %>
43 | 44 | <%= ff.check_box :chronic %> 45 | <%= ff.label :chronic %> 46 | 47 | <%= ff.label :diagnosis_date %>
48 | <%= ff.date_field :diagnosis_date, class: 'form-control' %> 49 | 50 | <%= ff.label :notes %>
51 | <%= ff.text_area :notes, class:'form-control' %>
52 | 53 | <%= ff.check_box :_destroy %> 54 | <%= ff.label :_destroy, "Remove" %> 55 |
56 |
57 | <% end %> 58 | 61 |
62 |
63 |
64 | <%= f.submit %> 65 |
66 | <% end %> -------------------------------------------------------------------------------- /.circleci/config.yml: -------------------------------------------------------------------------------- 1 | # Ruby CircleCI 2.0 configuration file 2 | # 3 | # Check https://circleci.com/docs/2.0/language-ruby/ for more details 4 | # 5 | version: 2 6 | jobs: 7 | build: 8 | environment: 9 | CC_TEST_REPORTER_ID: bb3d2bcc9ffe079c10061804fc1baf70959b2d1ac5294791085d6e64f44f18a7 10 | docker: 11 | - image: circleci/ruby:2.4.1-node-browsers 12 | environment: 13 | DATABASE_URL: "postgres://conexion_felina@localhost/conexion_felina-test" 14 | PGHOST: 127.0.0.1 15 | PGUSER: root 16 | RAILS_ENV: test 17 | RACK_ENV: test 18 | - image: postgres:9.5-alpine 19 | environment: 20 | POSTGRES_USER: conexion_felina 21 | POSTGRES_DB: conexion_felina-test 22 | 23 | working_directory: ~/conexion_felina 24 | 25 | steps: 26 | - checkout 27 | 28 | # Download and cache dependencies 29 | - restore_cache: 30 | keys: 31 | - v1-dependencies-{{ checksum "Gemfile.lock" }} 32 | # fallback to using the latest cache if no exact match is found 33 | - v1-dependencies- 34 | 35 | - run: 36 | name: install dependencies 37 | command: | 38 | bundle install --jobs=4 --retry=3 --path vendor/bundle 39 | 40 | - save_cache: 41 | paths: 42 | - ./vendor/bundle 43 | key: v1-dependencies-{{ checksum "Gemfile.lock" }} 44 | 45 | # Database setup 46 | - run: 47 | name: setup db 48 | command: | 49 | bundle exec rake db:create 50 | bundle exec rake db:migrate 51 | bundle exec rake db:schema:load 52 | 53 | # setup code climate coverage reporter 54 | - run: 55 | name: Setup Code Climate test-reporter 56 | command: | 57 | curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter 58 | chmod +x ./cc-test-reporter 59 | 60 | 61 | # run tests! 62 | - run: 63 | name: run tests 64 | command: | 65 | bundle exec rails db:seed RAILS_ENV=test 66 | ./cc-test-reporter before-build 67 | rspec 68 | ./cc-test-reporter after-build --exit-code $? 69 | 70 | deployment: 71 | staging: 72 | branch: master 73 | heroku: 74 | appname: conexionfelina -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | git_source(:github) do |repo_name| 4 | repo_name = "#{repo_name}/#{repo_name}" unless repo_name.include?('/') 5 | "https://github.com/#{repo_name}.git" 6 | end 7 | 8 | # Bundle edge Rails instead: gem 'rails', github: 'rails/rails' 9 | gem 'rails', '~> 5.2.3' 10 | # Use postgresql as the database for Active Record 11 | gem 'pg', '>= 0.18', '< 2.0' 12 | # Use Puma as the app server 13 | gem 'puma', '~> 3.7' 14 | # Use SCSS for stylesheets 15 | gem 'sass-rails', '~> 5.0' 16 | # Use Uglifier as compressor for JavaScript assets 17 | gem 'uglifier', '>= 1.3.0' 18 | # See https://github.com/rails/execjs#readme for more supported runtimes 19 | # gem 'therubyracer', platforms: :ruby 20 | gem 'sprockets' 21 | # Use CoffeeScript for .coffee assets and views 22 | gem 'coffee-rails', '~> 4.2' 23 | # Turbolinks makes navigating your web application faster. Read more: https://github.com/turbolinks/turbolinks 24 | gem 'turbolinks', '~> 5' 25 | # Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder 26 | gem 'jbuilder', '~> 2.8' 27 | # Use Redis adapter to run Action Cable in production 28 | # gem 'redis', '~> 4.0' 29 | # Use ActiveModel has_secure_password 30 | # gem 'bcrypt', '~> 3.1.7' 31 | 32 | # Use Capistrano for deployment 33 | # gem 'capistrano-rails', group: :development 34 | 35 | gem 'bootstrap', '~> 4.1.0' 36 | gem 'jquery-rails' 37 | 38 | gem 'high_voltage' 39 | 40 | gem 'devise' 41 | gem 'pundit' 42 | 43 | gem 'cocoon' 44 | gem 'wicked' 45 | 46 | group :development, :test do 47 | # Call 'byebug' anywhere in the code to stop execution and get a debugger console 48 | gem 'byebug', platforms: [:mri, :mingw, :x64_mingw] 49 | # Adds support for Capybara system testing and selenium driver 50 | gem 'capybara', '~> 3.12' 51 | gem 'selenium-webdriver' 52 | gem 'factory_bot_rails' 53 | gem 'rubocop' 54 | end 55 | 56 | group :development do 57 | # Access an IRB console on exception pages or by using <%= console %> anywhere in the code. 58 | gem 'rails_real_favicon' 59 | gem 'web-console', '>= 3.3.0' 60 | end 61 | 62 | group :test do 63 | gem 'rspec-activemodel-mocks' 64 | gem 'rspec-rails', '~> 3.8' 65 | 66 | gem 'simplecov' 67 | gem 'simplecov-console' 68 | 69 | gem 'rails-controller-testing' 70 | gem 'shoulda-matchers', '4.0.0.rc1' 71 | end 72 | 73 | # Windows does not include zoneinfo files, so bundle the tzinfo-data gem 74 | gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby] 75 | -------------------------------------------------------------------------------- /config/puma.rb: -------------------------------------------------------------------------------- 1 | # Puma can serve each request in a thread from an internal thread pool. 2 | # The `threads` method setting takes two numbers: a minimum and maximum. 3 | # Any libraries that use thread pools should be configured to match 4 | # the maximum value specified for Puma. Default is set to 5 threads for minimum 5 | # and maximum; this matches the default thread size of Active Record. 6 | # 7 | threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 } 8 | threads threads_count, threads_count 9 | 10 | # Specifies the `port` that Puma will listen on to receive requests; default is 3000. 11 | # 12 | port ENV.fetch("PORT") { 3000 } 13 | 14 | # Specifies the `environment` that Puma will run in. 15 | # 16 | environment ENV.fetch("RAILS_ENV") { "development" } 17 | 18 | # Specifies the number of `workers` to boot in clustered mode. 19 | # Workers are forked webserver processes. If using threads and workers together 20 | # the concurrency of the application would be max `threads` * `workers`. 21 | # Workers do not work on JRuby or Windows (both of which do not support 22 | # processes). 23 | # 24 | # workers ENV.fetch("WEB_CONCURRENCY") { 2 } 25 | 26 | # Use the `preload_app!` method when specifying a `workers` number. 27 | # This directive tells Puma to first boot the application and load code 28 | # before forking the application. This takes advantage of Copy On Write 29 | # process behavior so workers use less memory. If you use this option 30 | # you need to make sure to reconnect any threads in the `on_worker_boot` 31 | # block. 32 | # 33 | # preload_app! 34 | 35 | # If you are preloading your application and using Active Record, it's 36 | # recommended that you close any connections to the database before workers 37 | # are forked to prevent connection leakage. 38 | # 39 | # before_fork do 40 | # ActiveRecord::Base.connection_pool.disconnect! if defined?(ActiveRecord) 41 | # end 42 | 43 | # The code in the `on_worker_boot` will be called if you are using 44 | # clustered mode by specifying a number of `workers`. After each worker 45 | # process is booted, this block will be run. If you are using the `preload_app!` 46 | # option, you will want to use this block to reconnect to any threads 47 | # or connections that may have been created at application boot, as Ruby 48 | # cannot share connections between processes. 49 | # 50 | # on_worker_boot do 51 | # ActiveRecord::Base.establish_connection if defined?(ActiveRecord) 52 | # end 53 | # 54 | 55 | # Allow puma to be restarted by `rails restart` command. 56 | plugin :tmp_restart 57 | -------------------------------------------------------------------------------- /spec/validators/cat_validator_spec.rb: -------------------------------------------------------------------------------- 1 | require 'rails_helper' 2 | 3 | LORE_IPSUM_250 = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam pretium felis sit amet libero congue, sed bibendum tortor eleifend. Nam imperdiet pellentesque magna, sed consectetur est egestas vitae. Praesent tempus lacus nec finibus tincidunt amet.' 4 | LORE_IPSUM_513 = + LORE_IPSUM_250 + LORE_IPSUM_250 + "1234567890123" 5 | 6 | RSpec.describe Cat, :type => :model do 7 | 8 | def mock_relationships(cat) 9 | cat.colony = mock_model("Colony") 10 | end 11 | 12 | context 'given a cat with only name' do 13 | it 'must be valid' do 14 | valid_cat = Cat.new(name: "Kitty", saved_state: "active") 15 | mock_relationships(valid_cat) 16 | expect(valid_cat).to be_valid 17 | end 18 | end 19 | 20 | context 'given a cat without name' do 21 | it 'must not be valid' do 22 | valid_cat = Cat.new(saved_state: "active") 23 | mock_relationships(valid_cat) 24 | expect(valid_cat).to_not be_valid 25 | end 26 | end 27 | 28 | context 'given a cat with 21 characters name' do 29 | it 'must not be valid' do 30 | valid_cat = Cat.new(name: "123456789012345678901", saved_state: "active") 31 | mock_relationships(valid_cat) 32 | expect(valid_cat).to_not be_valid 33 | end 34 | end 35 | 36 | context 'given a cat with name and bio with 250 words' do 37 | it 'must be valid' do 38 | valid_cat = Cat.new(name: "Kitty", bio: LORE_IPSUM_250, saved_state: "active") 39 | mock_relationships(valid_cat) 40 | expect(valid_cat).to be_valid 41 | end 42 | end 43 | 44 | context 'given a cat with name and bio with 513 words' do 45 | it 'must not be valid' do 46 | valid_cat = Cat.new(name: "Kitty", bio: LORE_IPSUM_513, saved_state: "active") 47 | mock_relationships(valid_cat) 48 | expect(valid_cat).to_not be_valid 49 | end 50 | end 51 | 52 | context 'given a cat with name and birth_date which is yesterday' do 53 | it 'must be valid' do 54 | valid_cat = Cat.new(name: "Kitty", birthday_date: Date.yesterday, saved_state: "active") 55 | mock_relationships(valid_cat) 56 | expect(valid_cat).to be_valid 57 | end 58 | end 59 | 60 | context 'given a cat with name and birth_date which is tomorrow' do 61 | it 'must not be valid' do 62 | valid_cat = Cat.new(name: "Kitty", birthday_date: Date.tomorrow, saved_state: "active") 63 | mock_relationships(valid_cat) 64 | expect(valid_cat).to_not be_valid 65 | end 66 | end 67 | 68 | end 69 | -------------------------------------------------------------------------------- /docs/conventions.md: -------------------------------------------------------------------------------- 1 | # Development Conentions 2 | 3 | If you've just decided to contribute to the project's codebase, please read our 4 | [installation](installation.md) and [beginner](beginners.md) guides to get started. 5 | 6 | ## Back-end: Ruby on Rails 7 | 8 | ### Code Conventions 9 | We follow recommendations by [Airbnb's ruby style guide](https://github.com/airbnb/ruby). 10 | You may want to use [Rubocop](https://github.com/rubocop-hq/rubocop) as a 11 | static code analyzer to fulfill CodeClimate suggestions. 12 | 13 | ### Automated Testing 14 | We are using [rspec](https://github.com/rspec/rspec-rails) along with 15 | [shoulda-matchers](https://github.com/thoughtbot/shoulda-matchers) for our automated tests. 16 | 17 | You may run all tests by typing: 18 | ``` 19 | rspec 20 | ``` 21 | 22 | Or a single file: 23 | ``` 24 | rspec spec/models/cat_spec.rb 25 | ``` 26 | 27 | Or a even a specific block or line in a file: 28 | ``` 29 | rspec spec/models/cat_spec.rb:3 30 | ``` 31 | 32 | ## Front-end: React 33 | 34 | ### Code Conventions 35 | We are currently developing our front-end views by building 36 | [React](https://reactjs.org/) components along with 37 | [Storybook](https://storybook.js.org/). 38 | 39 | **MAKE SURE YOU DOWNLOAD THE LATEST CHANGES FROM THE `react` BRANCH FIRST** 40 | 41 | - All web UI components can be found at `app/javascript/bundles/UI/components` 42 | - All stories are found at `app/javascript/stories/ui` 43 | - All [Jest](https://jestjs.io/) tests lay on `app/javascript/spec` 44 | 45 | One of our main goals is to stick to 46 | [Airbnb's JavaScript style guide](https://github.com/airbnb/javascript) 47 | to make our code cleaner and clearer. 48 | 49 | 50 | ### Automated Testing 51 | - Install and configuration [here](https://blog.arkency.com/testing-react-dot-js-components-with-jest-in-rails-plus-webpacker-plus-webpack-environment/) 52 | we change the path to `app/javascript/spec`. 53 | - Write your tests in `app/javascript/spec/`. Quick start tutorial [here](https://medium.com/capital-one-developers/unit-testing-behavior-of-react-components-with-test-driven-development-ae15b03a3689) 54 | - You can test a file with `yarn test nameOfFile` for example `yarn test Input.test.js` if the file is in `app/javascript/spec`. 55 | - Or run all test files with `yarn test`. 56 | 57 | ### Component styling 58 | We are currently using CSS components for component styling. 59 | You can check out the following example to get started: 60 | 61 | https://github.com/gajus/react-css-modules#css-modules 62 | 63 | ### Starting storybook 64 | `npm run storybook` 65 | 66 | -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | [![CircleCI](https://circleci.com/gh/infusionvlc/ConexionFelina.svg?style=svg)](https://circleci.com/gh/infusionvlc/ConexionFelina) [![Maintainability](https://api.codeclimate.com/v1/badges/da388b7d223be8725dbd/maintainability)](https://codeclimate.com/github/infusionvlc/ConexionFelina/maintainability) [![security](https://hakiri.io/github/infusionvlc/ConexionFelina/master.svg)](https://hakiri.io/github/infusionvlc/ConexionFelina/master) 2 | 3 | # COVI (Conexión Felina) 4 | 5 | ## Este proyecto tiene como objetivo acercar a las personas la situación de los gatos de las colonias de Viveros 🐱❤️ 6 | 7 | Conexión Felina es una aplicación para hacer más fácil la labor de las personas voluntarias que cuidan de los gatos callejeros. Aquí vive todo el trabajo que nuestros colaboradores han hecho con mucho esfuerzo 💪 y, sobretodo, con mucho cariño ❤️. 8 | 9 | En COVI, parte de la comunidad **[INFUSIÓN](http://www.infusionvlc.com)**, creemos que la **diversidad** es una fuente de **riqueza** en todos los ámbitos y por eso queremos visibilizar y acoger a todas las personas, sea cual sea su género, sexo, edad, experiencia, origen, etc 👱🧔🏽👨‍🌾👵. Por eso, toda persona involucrada en la comunidad debe cumplir nuestro **[código de conducta](http://www.infusionvlc.com/reglas)** 🖐️. 10 | 11 | ## Cómo contribuir 12 | Nuestro equipo está formado por personas con experiencias muy diversas: desde desarrolladores 💻 a diseñadores 🎨 y traductores 💬. **Toda ayuda siempre es bienvenida** y siempre estamos buscando a más gente para participar en todos nuestros proyectos. 13 | 14 | Si te animas, [puedes enviarnos un email](mailto:hola@infusionvlc.com) 📮 y contarnos más sobre ti y en qué quieres echarnos una mano. Te enviaremos una invitación a nuestro equipo de trabajo. 15 | 16 | Si estás interesado/a en colaborar con nosotros en el desarrollo de la web, puedes encontrar las instrucciones en castellano, valenciano e inglés en [nuestra wiki](https://github.com/infusionvlc/ConexionFelina/wiki) 📓. 17 | 18 | 19 | ### Open Collective 20 | 21 | ¡Muchas gracias a todos los backers y los sponsors que aportáis vuestro granito de arena a la comunidad! [Tú también puedes unirte y ayudarnos a continuar haciendo posibles estos proyectos](https://opencollective.com/infusionvlc) 22 | 23 | 24 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![CircleCI](https://circleci.com/gh/infusionvlc/ConexionFelina.svg?style=svg)](https://circleci.com/gh/infusionvlc/ConexionFelina) 2 | [![Maintainability](https://api.codeclimate.com/v1/badges/da388b7d223be8725dbd/maintainability)](https://codeclimate.com/github/infusionvlc/ConexionFelina/maintainability) 3 | [![Test Coverage](https://api.codeclimate.com/v1/badges/da388b7d223be8725dbd/test_coverage)](https://codeclimate.com/github/infusionvlc/ConexionFelina/test_coverage) 4 | [![security](https://hakiri.io/github/infusionvlc/ConexionFelina/master.svg)](https://hakiri.io/github/infusionvlc/ConexionFelina/master) 5 | 6 | 7 | 8 | # COVI (Conexión Felina) 9 | 10 | Docs: https://infusionvlc.github.io/ConexionFelina/ 11 | 12 | ## Este proyecto tiene como objetivo acercar a las personas la situación de los gatos de las colonias de Viveros 🐱❤️ 13 | 14 | Conexión Felina es una aplicación para hacer más fácil la labor de las personas voluntarias que cuidan de los gatos callejeros. Aquí vive todo el trabajo que nuestros colaboradores han hecho con mucho esfuerzo 💪 y, sobretodo, con mucho cariño ❤️. 15 | 16 | En COVI, parte de la comunidad **[INFUSIÓN](http://www.infusionvlc.com)**, creemos que la **diversidad** es una fuente de **riqueza** en todos los ámbitos y por eso queremos visibilizar y acoger a todas las personas, sea cual sea su género, sexo, edad, experiencia, origen, etc 👱🧔🏽👨‍🌾👵 Por eso, toda persona involucrada en la comunidad debe cumplir nuestro **[código de conducta](http://www.infusionvlc.com/reglas)**. 🖐️ 17 | 18 | ## Cómo contribuir 19 | Nuestro equipo está formado por personas con experiencias muy diversas: desde desarrolladores 💻 a diseñadores 🎨 y traductores 💬. **Toda ayuda siempre es bienvenida** y siempre estamos buscando a más gente para participar en todos nuestros proyectos. 20 | 21 | Si te animas, [puedes enviarnos un email](mailto:hola@infusionvlc.com) 📮 y contarnos más sobre ti y en qué quieres echarnos una mano. Te enviaremos una invitación a nuestro equipo de trabajo. 22 | 23 | Si estás interesado/a en colaborar con nosotros en el desarrollo de la web, puedes encontrar instrucciones [nuestra wiki](https://github.com/infusionvlc/ConexionFelina/wiki). 📓 24 | 25 | 26 | ### Open Collective 27 | 28 | ¡Muchas gracias a todos los backers y los sponsors que aportáis vuestro granito de arena a la comunidad! [Tú también puedes unirte y ayudarnos a continuar haciendo posibles estos proyectos](https://opencollective.com/infusionvlc) 29 | 30 | 31 | -------------------------------------------------------------------------------- /spec/rails_helper.rb: -------------------------------------------------------------------------------- 1 | # This file is copied to spec/ when you run 'rails generate rspec:install' 2 | require 'spec_helper' 3 | ENV['RAILS_ENV'] ||= 'test' 4 | require File.expand_path('../../config/environment', __FILE__) 5 | # Prevent database truncation if the environment is production 6 | abort("The Rails environment is running in production mode!") if Rails.env.production? 7 | require 'rspec/rails' 8 | # Add additional requires below this line. Rails is not loaded until this point! 9 | require "capybara/rspec" 10 | require 'support/factory_bot' 11 | 12 | Rails.application.load_seed 13 | 14 | include Warden::Test::Helpers 15 | 16 | # Requires supporting ruby files with custom matchers and macros, etc, in 17 | # spec/support/ and its subdirectories. Files matching `spec/**/*_spec.rb` are 18 | # run as spec files by default. This means that files in spec/support that end 19 | # in _spec.rb will both be required and run as specs, causing the specs to be 20 | # run twice. It is recommended that you do not name files matching this glob to 21 | # end with _spec.rb. You can configure this pattern with the --pattern 22 | # option on the command line or in ~/.rspec, .rspec or `.rspec-local`. 23 | # 24 | # The following line is provided for convenience purposes. It has the downside 25 | # of increasing the boot-up time by auto-requiring all files in the support 26 | # directory. Alternatively, in the individual `*_spec.rb` files, manually 27 | # require only the support files necessary. 28 | # 29 | Dir[Rails.root.join('spec/support/**/*.rb')].each { |f| require f } 30 | 31 | # Checks for pending migrations and applies them before tests are run. 32 | # If you are not using ActiveRecord, you can remove this line. 33 | ActiveRecord::Migration.maintain_test_schema! 34 | 35 | RSpec.configure do |config| 36 | # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures 37 | config.fixture_path = "#{::Rails.root}/spec/fixtures" 38 | 39 | # If you're not using ActiveRecord, or you'd prefer not to run each of your 40 | # examples within a transaction, remove the following line or assign false 41 | # instead of true. 42 | config.use_transactional_fixtures = true 43 | 44 | # RSpec Rails can automatically mix in different behaviours to your tests 45 | # based on their file location, for example enabling you to call `get` and 46 | # `post` in specs under `spec/controllers`. 47 | # 48 | # You can disable this behaviour by removing the line below, and instead 49 | # explicitly tag your specs with their type, e.g.: 50 | # 51 | # RSpec.describe UsersController, :type => :controller do 52 | # # ... 53 | # end 54 | # 55 | # The different available types are documented in the features, such as in 56 | # https://relishapp.com/rspec/rspec-rails/docs 57 | config.infer_spec_type_from_file_location! 58 | 59 | # Filter lines from Rails gems in backtraces. 60 | config.filter_rails_from_backtrace! 61 | # arbitrary gems may also be filtered via: 62 | # config.filter_gems_from_backtrace("gem name") 63 | end 64 | 65 | Shoulda::Matchers.configure do |config| 66 | config.integrate do |with| 67 | with.test_framework :rspec 68 | with.library :rails 69 | end 70 | end 71 | -------------------------------------------------------------------------------- /docs/database.md: -------------------------------------------------------------------------------- 1 | # Database Schema 2 | 3 | You can check out the latest schema version on our 4 | [GitHub repo](https://github.com/infusionvlc/ConexionFelina/db/schema.png). 5 | 6 | ![Database Schema. Updated on 17th Nov. 2018](assets/db.png) 7 | 8 | --- 9 | 10 | ## Class Descriptions 11 | 12 | ## Cat 13 | A Cat object contains all basic information from a real cat. 14 | This cat may be a street cat or even an already adopted cat. 15 | 16 | Notes on some of this model's fields: 17 | * **Gender**: either `:male` or `:female` (or unknown) 18 | * **Sterilized**: either `:yes` or `:no` (or unknown) 19 | * **Document**: chip code or official document for the cat's identification 20 | 21 | ## Colony 22 | A Colony is a collection of [cats](#cat) living in a [location](#location). 23 | Each colony has a list of tasks that volunteers are able to manage and do. 24 | All colonies are independent of the rest and are managed by their volunteers 25 | exclusively. 26 | 27 | ## Location 28 | A Location is a real emplacement where colonies live. This object allows the 29 | application to store spatial information of colonies distribution. 30 | 31 | ## User 32 | Users are objects that let the application store information about real users, 33 | such as their adoptions, messages, tasks, etc. 34 | 35 | Notes on some of this model's fields: 36 | * **Role**: may be `:basic`, `:volunteer` or `:admin`. 37 | More on [user authorization here](pundit.md). 38 | * **Purrs**: amount of points this user has earned by purchasing 39 | [products](#product) or making [donations](#donation). 40 | 41 | ## Task 42 | A Task is some work that volunteers need to get done in a colony. It may be 43 | a one-time task or a recurring one. Tasks are [assigned](#assignment) to 44 | [volunteers](#user). All tasks may have one or more [turns](#turns), 45 | that allow volunteers to set up a responsible person for its execution. 46 | 47 | ## Turn 48 | A Turn has a start date and an end date in which specified [volunteers](#user) 49 | are responsible of the related task. 50 | 51 | ## Assignment 52 | Contains information about which [volunteers](#user) are responsible for a 53 | [task](#task) during a [turn](#turn). 54 | 55 | ## Illness 56 | An Illness contains basic information about a condition any [cat](#cat) may have, 57 | along with a description and some treatment guidelines. 58 | 59 | ## Suffering 60 | A Suffering specifiecs which [illness](#illness) a [cat](#cat) has got. 61 | It also contains a diagnosis date and a dischargement date, along with some notes. 62 | There's also a `chronic` field in case the condition may not be recoverable. 63 | 64 | ## Treatment Entry 65 | A Treatment Entry logs any action taken to combat a [suffering](#suffering) 66 | from a cat. 67 | 68 | ## Adoption 69 | An Adoption holds the date a [cat](#cat) was adopted by a [user](#user). 70 | 71 | ## Sponsor (sponsorship) 72 | Any [user](#user) is able to sponsor a [cat](#cat) by making a monthly donation 73 | to support a [**colony**](#colony). Volunteers will send them back updates and photos about their 74 | sponsored cat's life. 75 | 76 | Notes on some of this model's fields: 77 | * **Renovate**: a `boolean` field that stores if a sponsorhip 78 | 79 | ## Donation 80 | A Donation object holds any amount of money a [user](#user) has donated to the **project**. 81 | 82 | ## Work in progress... 83 | We're still defining how the store and chats will work... -------------------------------------------------------------------------------- /spec/validators/suffering_validator_spec.rb: -------------------------------------------------------------------------------- 1 | require "rails_helper" 2 | 3 | RSpec.describe SufferingValidator do 4 | def mock_relationships(suffering) 5 | suffering.cat = mock_model("Cat") 6 | suffering.illness = mock_model("Illness") 7 | end 8 | 9 | context 'when a suffering for a healty cat is created' do 10 | it 'should be valid with a status other than healthy and a dischargement date' do 11 | valid_suffering = Suffering.new(diagnosis_date: Date.today, notes: '', chronic: false, status: 0, dischargement_date: Date.today) 12 | mock_relationships(valid_suffering) 13 | expect(valid_suffering).to be_valid 14 | end 15 | 16 | it 'should not be valid with a healthy status and an empty dischargement date' do 17 | valid_suffering = Suffering.new(diagnosis_date: Date.today, notes: '', chronic: false, status: 4, dischargement_date: nil) 18 | mock_relationships(valid_suffering) 19 | expect(valid_suffering).to_not be_valid 20 | end 21 | 22 | it 'should be valid with a healthy status and an dischargement date' do 23 | valid_suffering = Suffering.new(diagnosis_date: Date.today, notes: '', chronic: false, status: 4, dischargement_date: Date.today) 24 | mock_relationships(valid_suffering) 25 | expect(valid_suffering).to be_valid 26 | end 27 | 28 | it 'should be valid with a status other than healthy and an empty dischargement date' do 29 | valid_suffering = Suffering.new(diagnosis_date: Date.today, notes: '', chronic: false, status: 0, dischargement_date: nil) 30 | mock_relationships(valid_suffering) 31 | expect(valid_suffering).to be_valid 32 | end 33 | 34 | it 'should not be valid with a nil status and a nil dischargement_date' do 35 | valid_suffering = Suffering.new(diagnosis_date: Date.today, notes: '', chronic: false, status: nil, dischargement_date: nil) 36 | mock_relationships(valid_suffering) 37 | expect(valid_suffering).to_not be_valid 38 | end 39 | 40 | it 'should not be valid with a nil status and a dischargement_date' do 41 | valid_suffering = Suffering.new(diagnosis_date: Date.today, notes: '', chronic: false, status: nil, dischargement_date: Date.today) 42 | mock_relationships(valid_suffering) 43 | expect(valid_suffering).to_not be_valid 44 | end 45 | end 46 | 47 | context "given a suffering with a diagnosis date earlier than today" do 48 | it "must be valid" do 49 | valid_suffering = Suffering.new(diagnosis_date: Date.yesterday, notes: '', chronic: false, status: 4, dischargement_date: Date.today) 50 | mock_relationships(valid_suffering) 51 | expect(valid_suffering).to be_valid 52 | end 53 | end 54 | 55 | context "given a suffering with a diagnosis date equal to today" do 56 | it "must be valid" do 57 | valid_suffering = Suffering.new(diagnosis_date: Date.today, notes: '', chronic: false, status: 4, dischargement_date: Date.today) 58 | mock_relationships(valid_suffering) 59 | 60 | expect(valid_suffering).to be_valid 61 | end 62 | end 63 | 64 | context "given a suffering with a diagnosis date later than today" do 65 | it "must be invalid" do 66 | invalid_suffering = Suffering.new(diagnosis_date: Date.tomorrow) 67 | mock_relationships(invalid_suffering) 68 | 69 | expect(invalid_suffering).to_not be_valid 70 | end 71 | end 72 | end 73 | -------------------------------------------------------------------------------- /config/database.yml: -------------------------------------------------------------------------------- 1 | # PostgreSQL. Versions 9.1 and up are supported. 2 | # 3 | # Install the pg driver: 4 | # gem install pg 5 | # On OS X with Homebrew: 6 | # gem install pg -- --with-pg-config=/usr/local/bin/pg_config 7 | # On OS X with MacPorts: 8 | # gem install pg -- --with-pg-config=/opt/local/lib/postgresql84/bin/pg_config 9 | # On Windows: 10 | # gem install pg 11 | # Choose the win32 build. 12 | # Install PostgreSQL and put its /bin directory on your path. 13 | # 14 | # Configure Using Gemfile 15 | # gem 'pg' 16 | # 17 | default: &default 18 | adapter: postgresql 19 | encoding: unicode 20 | # For details on connection pooling, see Rails configuration guide 21 | # http://guides.rubyonrails.org/configuring.html#database-pooling 22 | pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> 23 | 24 | development: 25 | <<: *default 26 | database: conexion_felina_development 27 | 28 | # The specified database role being used to connect to postgres. 29 | # To create additional roles in postgres see `$ createuser --help`. 30 | # When left blank, postgres will use the default role. This is 31 | # the same name as the operating system user that initialized the database. 32 | username: postgres 33 | 34 | # The password associated with the postgres role (username). 35 | password: postgres 36 | 37 | # Connect on a TCP socket. Omitted by default since the client uses a 38 | # domain socket that doesn't need configuration. Windows does not have 39 | # domain sockets, so uncomment these lines. 40 | #host: localhost 41 | 42 | # The TCP port the server listens on. Defaults to 5432. 43 | # If your server runs on a different port number, change accordingly. 44 | #port: 5432 45 | 46 | # Schema search path. The server defaults to $user,public 47 | #schema_search_path: myapp,sharedapp,public 48 | 49 | # Minimum log levels, in increasing order: 50 | # debug5, debug4, debug3, debug2, debug1, 51 | # log, notice, warning, error, fatal, and panic 52 | # Defaults to warning. 53 | #min_messages: notice 54 | 55 | # Warning: The database defined as "test" will be erased and 56 | # re-generated from your development database when you run "rake". 57 | # Do not set this db to the same as development or production. 58 | test: 59 | <<: *default 60 | database: conexion_felina_test 61 | username: postgres 62 | password: postgres 63 | 64 | # As with config/secrets.yml, you never want to store sensitive information, 65 | # like your database password, in your source code. If your source code is 66 | # ever seen by anyone, they now have access to your database. 67 | # 68 | # Instead, provide the password as a unix environment variable when you boot 69 | # the app. Read http://guides.rubyonrails.org/configuring.html#configuring-a-database 70 | # for a full rundown on how to provide these environment variables in a 71 | # production deployment. 72 | # 73 | # On Heroku and other platform providers, you may have a full connection URL 74 | # available as an environment variable. For example: 75 | # 76 | # DATABASE_URL="postgres://myuser:mypass@localhost/somedatabase" 77 | # 78 | # You can use this database configuration with: 79 | # 80 | # production: 81 | # url: <%= ENV['DATABASE_URL'] %> 82 | # 83 | production: 84 | <<: *default 85 | database: conexion_felina_production 86 | username: conexion_felina 87 | password: <%= ENV['CONEXION_FELINA_DATABASE_PASSWORD'] %> 88 | -------------------------------------------------------------------------------- /public/instagram.svg: -------------------------------------------------------------------------------- 1 | 2 | 17 | 19 | 20 | 22 | image/svg+xml 23 | 25 | Instagram icon 26 | 27 | 28 | 29 | 31 | 51 | Instagram icon 53 | 57 | 58 | --------------------------------------------------------------------------------