diff --git a/.nvmrc b/.nvmrc index 958b5a36e..6f7f377bf 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -v14 +v16 diff --git a/Gemfile b/Gemfile index e1b737c6c..fa2ef2dc8 100644 --- a/Gemfile +++ b/Gemfile @@ -17,7 +17,6 @@ gem "sass-rails", ">= 6" gem "hotwire-rails" gem "importmap-rails", "~> 1.1" gem "bootstrap" -gem "jquery-rails" # Use Active Model has_secure_password # gem 'bcrypt', '~> 3.1.7' gem "acts_as_singleton" @@ -119,3 +118,4 @@ gem "ransack" gem "rails_db", "~> 2.4" gem "meta-tags" gem "inline_svg" +gem "breadcrumbs_on_rails" diff --git a/Gemfile.lock b/Gemfile.lock index 600e65e32..a1d729524 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -109,6 +109,8 @@ GEM bootstrap (5.3.2) autoprefixer-rails (>= 9.1.0) popper_js (>= 2.11.8, < 3) + breadcrumbs_on_rails (4.1.0) + railties (>= 5.0) brow (0.4.1) builder (3.2.4) cancancan (3.3.0) @@ -254,10 +256,6 @@ GEM jbuilder (2.11.5) actionview (>= 5.0.0) activesupport (>= 5.0.0) - jquery-rails (4.6.0) - rails-dom-testing (>= 1, < 3) - railties (>= 4.2.0) - thor (>= 0.14, < 2.0) json (2.6.3) jsonapi-renderer (0.2.2) jwt (2.3.0) @@ -613,6 +611,7 @@ DEPENDENCIES bigdecimal (= 3.0.2) bootsnap (>= 1.4.4) bootstrap + breadcrumbs_on_rails cancancan (~> 3.3) capistrano (~> 3.11) capistrano-passenger (~> 0.2.0) @@ -642,7 +641,6 @@ DEPENDENCIES inline_svg it jbuilder (~> 2.7) - jquery-rails kaminari letter_opener listen (~> 3.3) diff --git a/README.md b/README.md index a23d1f3e9..6c5aa996f 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,11 @@ SoftServe IT Academy # ZERO WASTE + #### [Staging](https://zero-waste-staging.onrender.com/) # 1. About the project + zero-waste Zero Waste Lviv is a Public Organization that works on the implementation of waste reduction principles in Lviv and Ukraine. Organization draws attention of the city and businesses by conducting trainings, meetings, workshops and research to support ‘zero waste’ grounds. Organization conducts a campaign to draw attention to the problem of using disposable hygiene products for women and children and possible ways or reduction. Website - https://zerowastelviv.org.ua @@ -20,18 +22,21 @@ In order to attract attention to financial and ecological consequences of dispos - [Git-hook pre-commit](#Git-hook-pre-commit) ## Deployed Apps and Environments + The latest version from the 'develop' branch is automatically deployed to stage environment in Render, [staging link](https://zero-waste-staging.onrender.com/). The latest version from the release branch 'master' is automatically deployed to Production environment, [production link](http://calc.zerowastelviv.org.ua/). ## Installation -* Start the project locally + +- Start the project locally + # Required to install + - Ruby 3.2.2 - Ruby on Rails 7.1.2 - PostgreSQL 12 - Puma as a web server - Yarn -- jQuery - Bootstrap ## Clone @@ -39,17 +44,26 @@ The latest version from the release branch 'master' is automatically deployed to $ `git clone https://github.com/ita-social-projects/ZeroWaste.git` ## Local setup + First of all you need RVM to setup project. For the operating system Windows the optimal solution is to use WSL. $ `bin/setup` or $ `bundle install` +Install the following packages: + +`sudo apt install imagemagick` + +`sudo apt install libvips42` + PostgreSQL Install PostgreSQL for your operating system or subsystem. You can familiarize yourself with PostgreSQL documentation. +To check if it is installed and running correctly run `sudo systemctl status postgresql` + In your local machine in cloned project in config folder rename database.yml.sample to database.yml. Make sure that the user and password match the data in this file. Port may be changed. For further work, make sure that you have a user 'postgres' with superuser. If is no that one do next: @@ -68,7 +82,6 @@ $ `sudo apt-get install libpq-dev` then $ `gem install pg` - Database configure For correct operation of the migration, you need to rename the migration file `20220123171144_create_versions.rb` so that it is processed first. @@ -98,6 +111,8 @@ echo "deb [signed-by=/usr/share/keyrings/redis-archive-keyring.gpg] https://pack $ `sudo apt-get update` $ `sudo apt-get install redis` +To check if it is installed and running correctly run `sudo systemctl status redis` + npm and Node.js Also you need Node.js. @@ -131,10 +146,10 @@ $ `bundle add sidekiq` ## How to run local -1. Open terminal. -In some systems, after restarting them, the postgresql server remains disabled, perhaps at the first start you should enter `sudo service postgresql start`. -2. Run `rails server`/`rails s` to start application -3. Open http://localhost:3000 to view it in the browser. +1. Ensure that postgresql and redis are running +2. Run `rails assets:precompile` to precompile assets +3. Run `bin/rails tailwindcss:watch` with `rails server` to watch for changes in tailwind and start server or run `bin/dev` +4. Open http://localhost:3000 to view it in the browser. Solutions when an errors occurs: psql: FATAL: role "postgres" does not exist @@ -147,6 +162,7 @@ $ `yarn install` # Usage # How to run Rubocop + Running rubocop with no arguments will check all Ruby source files in the current folder: $ `rubocop` @@ -160,6 +176,7 @@ For more details check the available command-line options: $ `rubocop -h` # Git-hook pre-commit + Before using `git-hook-pre-commit` you need to install `sudo apt-get install cmake` For using `git-hook-pre-commit` type `cp git-hooks/pre-commit .git/hooks/pre-commit` command to install your hook. diff --git a/app/assets/images/icons/arrow-left.svg b/app/assets/images/icons/arrow-left.svg index fbb3a963f..9d3c82985 100644 --- a/app/assets/images/icons/arrow-left.svg +++ b/app/assets/images/icons/arrow-left.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/app/assets/images/icons/chevron-right.svg b/app/assets/images/icons/chevron-right.svg new file mode 100644 index 000000000..b118b171c --- /dev/null +++ b/app/assets/images/icons/chevron-right.svg @@ -0,0 +1,3 @@ + + + diff --git a/app/assets/stylesheets/application.tailwind.css b/app/assets/stylesheets/application.tailwind.css index 294a57507..31c8e7fc0 100644 --- a/app/assets/stylesheets/application.tailwind.css +++ b/app/assets/stylesheets/application.tailwind.css @@ -8,3 +8,4 @@ @import "./components/form.css"; @import "/components/account-footer"; @import "/components/pagination"; +@import "/components/breadcrumbs.scss"; diff --git a/app/assets/stylesheets/components/breadcrumbs.scss b/app/assets/stylesheets/components/breadcrumbs.scss new file mode 100644 index 000000000..32bbba11f --- /dev/null +++ b/app/assets/stylesheets/components/breadcrumbs.scss @@ -0,0 +1,18 @@ +@import "common_sizes.scss"; + +@layer components { + .breadcrumbs { + @apply flex w-full mx-auto mb-4 text-light_gray; + max-width: $max_width_content; + } + + .breadcrumbs ol a { + @apply text-success font-bold; + } + + .breadcrumbs ol a:hover { + text-decoration: underline; + text-underline-offset: 0.4em; + color: #7ca718; + } +} diff --git a/app/assets/stylesheets/components/header.css b/app/assets/stylesheets/components/header.css index cd77434fd..89680ce90 100644 --- a/app/assets/stylesheets/components/header.css +++ b/app/assets/stylesheets/components/header.css @@ -1,14 +1,15 @@ @layer components { .page-header { - @apply w-full xl:max-w-fit mx-auto mb-4 flex border-b-2 border-gray justify-center; + @apply flex w-full mx-auto mb-1 border-b-2 border-gray; + max-width: $max_width_content; } .tab { - @apply flex-row xl:flex whitespace-nowrap uppercase text-sm text-white border-b-2 border-transparent transition duration-500 ease-in-out hover:border-success py-6 px-4; + @apply flex-row px-4 py-6 text-sm text-white uppercase transition duration-500 ease-in-out border-b-2 border-transparent xl:flex whitespace-nowrap hover:border-success; } .tab-main-page { - @apply flex-row xl:flex whitespace-nowrap uppercase text-sm text-white border-b-2 border-transparent transition duration-500 ease-in-out hover:border-success py-4 px-6; + @apply flex-row px-6 py-4 text-sm text-white uppercase transition duration-500 ease-in-out border-b-2 border-transparent xl:flex whitespace-nowrap hover:border-success; } .header-btns { diff --git a/app/controllers/calculators_controller.rb b/app/controllers/calculators_controller.rb index 186ccc413..0051ba41a 100644 --- a/app/controllers/calculators_controller.rb +++ b/app/controllers/calculators_controller.rb @@ -23,6 +23,8 @@ def calculate def calculator @diaper_categories = Category.ordered_by_diapers_periods_price @preferable_category = Category.preferable.first + add_breadcrumb t("breadcrumbs.home"), root_path + add_breadcrumb t(".new_calculator.diaper_сalculator") if Flipper[:new_calculator_design].enabled? render "calculators/new_calculator" diff --git a/app/controllers/home_controller.rb b/app/controllers/home_controller.rb index 9c43de829..f4b191918 100644 --- a/app/controllers/home_controller.rb +++ b/app/controllers/home_controller.rb @@ -5,5 +5,7 @@ def index end def about + add_breadcrumb t("breadcrumbs.home"), root_path + add_breadcrumb t("about_us.title") end end diff --git a/app/controllers/messages_controller.rb b/app/controllers/messages_controller.rb index c7129ae2f..9a7f57cb7 100644 --- a/app/controllers/messages_controller.rb +++ b/app/controllers/messages_controller.rb @@ -3,6 +3,8 @@ class MessagesController < ApplicationController def new @message = Message.new + add_breadcrumb t("breadcrumbs.home"), root_path + add_breadcrumb t(".contact_us_header") end def create diff --git a/app/javascript/ajax/checkbox.js b/app/javascript/ajax/checkbox.js deleted file mode 100644 index cedc9da44..000000000 --- a/app/javascript/ajax/checkbox.js +++ /dev/null @@ -1,10 +0,0 @@ -jQuery(document).ready(function($){ - $(".calculate-btn").on('click', function(){ - if($("#checkbox_submit").prop('checked')){ - $.ajax({ - type: "POST", - url: "/receive_recomendations" - }) - } - }) -}); diff --git a/app/javascript/ajax/result_button.js b/app/javascript/ajax/result_button.js deleted file mode 100644 index 772be1a29..000000000 --- a/app/javascript/ajax/result_button.js +++ /dev/null @@ -1,27 +0,0 @@ -$(document).on('turbo:load', function() { - const form = document.getElementById('form'); - if (!form) { - return - } - - form.addEventListener('submit', function(e) { - - e.preventDefault(); - - const formData = { - childs_birthday: $("#birth").val() - } - $.ajax({ - url: "/api/v1/calculators/diapers-calculator/compute", - type: "POST", - data: formData, - dataType: "json", - success: function(data) { - for (var i = data.result.length - 1; i >= 0; i--) { - const oneItemFromArray = data.result[i] - $('[data-type="' + oneItemFromArray.name + '"]').text(oneItemFromArray.result); - } - } - }) - }); -}) diff --git a/app/javascript/application.js b/app/javascript/application.js index f0f77ce64..037127e97 100644 --- a/app/javascript/application.js +++ b/app/javascript/application.js @@ -1,7 +1,6 @@ // Configure your import map in config/importmap.rb. Read more: https://github.com/rails/importmap-rails import "controllers"; import "channels"; -import "jquery" import "@hotwired/turbo-rails"; import "bootstrap"; import "@fortawesome/fontawesome-free"; diff --git a/app/javascript/controllers/price_form_controller.js b/app/javascript/controllers/price_form_controller.js index aa65bd53e..9ecdf8479 100644 --- a/app/javascript/controllers/price_form_controller.js +++ b/app/javascript/controllers/price_form_controller.js @@ -1,7 +1,7 @@ -import { Controller } from "@hotwired/stimulus" +import { Controller } from "@hotwired/stimulus"; export default class extends Controller { - static targets = [ "priceInput", "price", "checkbox", "hiddenField" ] + static targets = ["priceInput", "price", "checkbox", "hiddenField", "errorMessage"]; connect() { for(let i = 0; i < this.checkboxTargets.length; i++) { @@ -10,6 +10,10 @@ export default class extends Controller { this.priceTargets[i].hidden = true } } + + this.priceInputTargets.forEach(input => { + input.addEventListener('input', this.validatePriceInput.bind(this)); + }); } togglePrice(event) { @@ -37,4 +41,20 @@ export default class extends Controller { this.hiddenFieldTargets[i].value = !this.checkboxTargets[i].checked } } + + validatePriceInput(event) { + const target = event.target; + const inputValue = target.value; + const regex = /^[\d.]+$/; + + const errorMessage = target.closest('.hidden-sum').querySelector('.error-message'); + + if (!regex.test(inputValue)) { + errorMessage.style.display = "block"; + target.style.borderColor = "red"; + } else { + errorMessage.style.display = "none"; + target.style.borderColor = ""; + } + } } diff --git a/app/javascript/js/calculators/edit.js b/app/javascript/js/calculators/edit.js deleted file mode 100644 index 9486bee24..000000000 --- a/app/javascript/js/calculators/edit.js +++ /dev/null @@ -1,57 +0,0 @@ -$(document).on('turbolinks:load', () => { - const page = document.getElementById('calculators-edit'); - if (!page) return - - const $fieldKindSelect = $('#calculator_fields_kind') - const $fieldTypeSelect = $('#calculator_fields_type') - const $fieldSubmitButton = $('#add-calculator-field') - const TYPES = $fieldKindSelect.data('fields-list') - - $fieldKindSelect.on('change', (e) => { - const data = TYPES[e.currentTarget.value] - - if (data && data.length) { - const optionsForSelect = data.map((fieldType) => { - return `` - }) - const placeholderOption = '' - - $fieldTypeSelect.prop('disabled', false) - $fieldTypeSelect.html(placeholderOption + optionsForSelect) - } else { - $fieldTypeSelect.prop('disabled', true) - $fieldTypeSelect.html('') - $fieldSubmitButton.addClass('disabled') - } - }) - - $fieldTypeSelect.on('change', (e) => { - if (e.currentTarget.value) { - $fieldSubmitButton.removeClass('disabled') - } else { - $fieldSubmitButton.addClass('disabled') - } - }) - - $fieldSubmitButton.on('click', (e) => { - e.preventDefault() - - const url = $fieldSubmitButton.data('url') - - $.ajax({ - url: url, - type: 'GET', - dataType: 'SCRIPT', - data: { - field: { - kind: $fieldKindSelect.val(), - type: $fieldTypeSelect.val() - } - }, - success: () => { - $fieldKindSelect.val('') - $fieldKindSelect.trigger('change') - } - }) - }) -}) diff --git a/app/javascript/plugins/flatpickr.js b/app/javascript/plugins/flatpickr.js deleted file mode 100644 index aaa3ead5f..000000000 --- a/app/javascript/plugins/flatpickr.js +++ /dev/null @@ -1,11 +0,0 @@ -require('flatpickr/dist/themes/material_green.css'); -const flatpickr = require('flatpickr'); - -$(function () { - $('.datepick').flatpickr({ - altInput: true, - altFormat: 'F j, Y', - dateFormat: 'Y-m-d', - maxDate: 'today', - }); -}); diff --git a/app/views/account/messages/show.html.erb b/app/views/account/messages/show.html.erb index 5ca56a2d0..b9c342084 100644 --- a/app/views/account/messages/show.html.erb +++ b/app/views/account/messages/show.html.erb @@ -1,5 +1,5 @@ <%= link_to account_messages_path, class: "rounded mt-3 px-2 flex items-center" do %> - <%= image_tag "icons/arrow-left.svg", class: "z-1 mr-2 mb-0.5" %> + <%= inline_svg "icons/arrow-left.svg", class: "z-1 mr-2 mb-0.5" %> <%= t('buttons.back') %> <% end %>
diff --git a/app/views/account/products/partials/edit/_form.html.erb b/app/views/account/products/partials/edit/_form.html.erb index 92765e727..ce13d5ccf 100644 --- a/app/views/account/products/partials/edit/_form.html.erb +++ b/app/views/account/products/partials/edit/_form.html.erb @@ -11,6 +11,7 @@ <%= prices_form.input :sum, label: false, input_html: { placeholder: t('.form.sum'), data: { price_form_target: 'priceInput' } } %> <%= prices_form.hidden_field :category_id, value: prices_form.object.category.id %> <%= prices_form.hidden_field :_destroy, data: { price_form_target: 'hiddenField' } %> + <% end %> diff --git a/app/views/account/products/partials/new/_form.html.erb b/app/views/account/products/partials/new/_form.html.erb index a5ea2faef..1d00064f1 100644 --- a/app/views/account/products/partials/new/_form.html.erb +++ b/app/views/account/products/partials/new/_form.html.erb @@ -10,6 +10,7 @@ <%= f.simple_fields_for :prices, f.object.find_or_build_price_for_category(category) do |prices_form| %> <%= prices_form.input :sum, label: false, input_html: { placeholder: t(".form.sum"), data: { price_form_target: "priceInput" } } %> <%= prices_form.hidden_field :category_id, value: category.id %> + <% end %> diff --git a/app/views/account/shared/_navigation.html.erb b/app/views/account/shared/_navigation.html.erb index 2809b9431..c14744ef9 100644 --- a/app/views/account/shared/_navigation.html.erb +++ b/app/views/account/shared/_navigation.html.erb @@ -1,9 +1,8 @@ -