diff --git a/.env.example b/.env.example index 0a71cacae..329465ffd 100644 --- a/.env.example +++ b/.env.example @@ -8,16 +8,22 @@ # Your local .env file is added to .gitignore and # wont be uploaded to the repo. - -# database setup +# Database setup DATABASE_USER=postgres DATABASE_NAME=timeoverflow_development -# host part of the url for mail links: +# Host part of the url for mail links: MAIL_LINK_HOST=localhost:3000 MAIL_LINK_PROTO=http -# a list of emails for superadmin users +# Email provider +SMTP_PASSWORD=XXXXXXXX +SMTP_DOMAIN=www.timeoverflow.org +SMTP_USER_NAME=my_username@timeoverflow.org +SMTP_ADDRESS=smtp.mailgun.org +SMTP_PORT=587 + +# List of emails for superadmin users ADMINS="admin@timeoverflow.org" # AWS settings diff --git a/README.md b/README.md index c08cc6ea1..1479d11a2 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # TimeOverflow -[![View performance data on Skylight](https://badges.skylight.io/problem/grDTNuzZRnyu.svg)](https://oss.skylight.io/app/applications/grDTNuzZRnyu) +[![View performance data on Skylight](https://badges.skylight.io/typical/grDTNuzZRnyu.svg)](https://oss.skylight.io/app/applications/grDTNuzZRnyu) [![Build Status](https://github.com/coopdevs/timeoverflow/actions/workflows/ci.yml/badge.svg?branch=develop)](https://github.com/coopdevs/timeoverflow/actions) [![Maintainability](https://api.codeclimate.com/v1/badges/f82c6d98a2441c84f2ef/maintainability)](https://codeclimate.com/github/coopdevs/timeoverflow/maintainability) [![Test Coverage](https://api.codeclimate.com/v1/badges/f82c6d98a2441c84f2ef/test_coverage)](https://codeclimate.com/github/coopdevs/timeoverflow/test_coverage) diff --git a/app/admin/category.rb b/app/admin/category.rb index 9a80ac39d..aff173567 100644 --- a/app/admin/category.rb +++ b/app/admin/category.rb @@ -2,7 +2,7 @@ index do id_column column :name do |category| - "#{tag.span(nil, class: "glyphicon glyphicon-#{category.icon_name}")} #{category.name}".html_safe + "#{category_icon(category)} #{category.name}".html_safe end actions end @@ -17,9 +17,12 @@ show do |cat| attributes_table do + row :name do + "#{category_icon(cat)} #{cat.name}".html_safe + end + row :icon_name row :created_at row :updated_at - row :icon_name row :name_translations do render_translations(cat.name_translations) end diff --git a/app/admin/dashboard.rb b/app/admin/dashboard.rb index 647b6d254..410315912 100644 --- a/app/admin/dashboard.rb +++ b/app/admin/dashboard.rb @@ -2,6 +2,16 @@ menu priority: 1, label: proc { I18n.t("active_admin.dashboard") } content title: proc { I18n.t("active_admin.dashboard") } do + columns do + panel "Global Stats", class: "global_stats_panel" do + div { "#{glyph(:home)} Time Banks #{Organization.count}".html_safe } + div { "#{glyph(:user)} Users #{User.count}".html_safe } + div { "#{glyph(:hand_up)} Offers #{Offer.count}".html_safe } + div { "#{glyph(:bell)} Inquiries #{Inquiry.count}".html_safe } + div { "#{glyph(:transfer)} Transfers #{Transfer.count}".html_safe } + end + end + columns do column do panel "Recent Organizations" do @@ -32,6 +42,16 @@ end end end + + column do + panel "Recent Petitions" do + ul do + Petition.last(5).map do |petition| + li "#{petition.user} #{glyph(:arrow_right)} #{petition.organization}".html_safe + end + end + end + end end end end diff --git a/app/admin/document.rb b/app/admin/document.rb index 55c9d0fa8..778c53cef 100644 --- a/app/admin/document.rb +++ b/app/admin/document.rb @@ -20,7 +20,7 @@ render_translations(t.title_translations) end row :content_translations do - render_translations(t.content_translations, "
") + render_translations(t.content_translations, "
") end end end diff --git a/app/admin/organization.rb b/app/admin/organization.rb index 825cb1937..c54442bc0 100644 --- a/app/admin/organization.rb +++ b/app/admin/organization.rb @@ -1,7 +1,15 @@ ActiveAdmin.register Organization do index do id_column - column :name + column :name do |organization| + output = tag.p organization.name + + if organization.logo.attached? + output << image_tag(organization.logo.variant(resize: "40^x")) + end + + output.html_safe + end column :created_at do |organization| l organization.created_at.to_date, format: :long end @@ -9,9 +17,24 @@ column :neighborhood column :email column :phone + column :members do |organization| + organization.members.count + end + column :posts do |organization| + organization.posts.count + end actions end + show do + div do + if organization.logo.attached? + image_tag(organization.logo.variant(resize: "100^x")) + end + end + default_main_content + end + form do |f| f.inputs do f.input :name @@ -23,6 +46,7 @@ f.input :address f.input :description f.input :public_opening_times + f.input :logo, as: :file end f.actions end @@ -47,5 +71,5 @@ def destroy filter :neighborhood permit_params :name, :email, :web, :phone, :city, :neighborhood, - :address, :description, :public_opening_times + :address, :description, :public_opening_times, :logo end diff --git a/app/admin/petition.rb b/app/admin/petition.rb index f0c88c5ba..fefe30e53 100644 --- a/app/admin/petition.rb +++ b/app/admin/petition.rb @@ -6,7 +6,9 @@ column :user column :organization column :created_at - column :status + column :status do |petition| + petition.status.upcase + end end filter :status, as: :select, collection: -> { Petition.statuses } diff --git a/app/admin/user.rb b/app/admin/user.rb index 2bec1c543..032375bc1 100644 --- a/app/admin/user.rb +++ b/app/admin/user.rb @@ -23,6 +23,9 @@ column :organizations do |u| u.organizations.map(&:to_s).join(", ") end + column :posts do |u| + u.posts.count + end actions end @@ -31,6 +34,7 @@ filter :username filter :phone filter :postcode + filter :locale form do |f| f.semantic_errors *f.object.errors.keys @@ -40,9 +44,10 @@ f.input :phone f.input :postcode f.input :gender, as: :select, collection: User::GENDERS + f.input :locale, as: :select, collection: I18n.available_locales end f.inputs "Memberships" do - f.has_many :members do |m| + f.has_many :members, allow_destroy: true do |m| m.input :organization, collection: Organization.order(id: :asc).pluck(:name, :id) m.input :active m.input :manager @@ -78,6 +83,6 @@ end end - permit_params :username, :email, :phone, :postcode, :gender, - members_attributes: [:organization_id, :active, :manager] + permit_params :username, :email, :phone, :postcode, :gender, :locale, + members_attributes: [:id, :organization_id, :active, :manager, :_destroy] end diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index 32ae40c1f..69e93281b 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -9,19 +9,12 @@ $(document).on('click', 'a[data-popup]', function(event) { $(document).on('click', 'span.show-password', function(event) { event.preventDefault(); - var inputType = 'text'; - var icon = 'visibility_off'; + var input = $(this).prev('input'); + var icon = $(this).find('.glyphicon'); - if ($(this).hasClass('checked')) { - $(this).removeClass('checked'); - inputType = 'password'; - icon = 'visibility'; - } else { - $(this).addClass('checked'); - } - - $(this).prev('input').attr('type', inputType); - $(this).find('.material-icons').html(icon); + $(input).attr('type', input[0].type === 'password' ? 'text' : 'password'); + $(icon).toggleClass('glyphicon-eye-close'); + $(icon).toggleClass('glyphicon-eye-open'); }); $(function() { diff --git a/app/assets/stylesheets/active_admin.scss b/app/assets/stylesheets/active_admin.scss index 46fb8521f..e19fdeefd 100644 --- a/app/assets/stylesheets/active_admin.scss +++ b/app/assets/stylesheets/active_admin.scss @@ -8,3 +8,15 @@ $table-stripe-color: #f5f5f5; @import "bootstrap-sprockets"; @import "bootstrap/variables"; @import "bootstrap/glyphicons"; + +.global_stats_panel div { + display: flex; + justify-content: space-between; + align-items: baseline; + gap: 5px; + font-size: 18px; + + b { + font-size: 20px; + } +} diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss index 606f11684..3c4ad3f5e 100644 --- a/app/assets/stylesheets/application.scss +++ b/app/assets/stylesheets/application.scss @@ -51,10 +51,6 @@ html { padding: 0; } - form .material-icons { - color: $form-input-glyph; - } - input { background-color: $form-input-bg-color; border-radius: 0.3rem; @@ -450,10 +446,6 @@ label[required]::after{ } .login-page { - .material-icons { - font-size: 3rem; - } - .checkbox { color: $form-login-gray-text; font-size: 1.6rem; @@ -568,6 +560,7 @@ label[required]::after{ .feature-icon { float: left; + margin-right: 2rem; } .features .first { @@ -584,12 +577,6 @@ label[required]::after{ padding-top: 3.5rem; } - .features .material-icons { - margin-right: 2rem; - position: relative; - top: 0.2rem; - } - .banner { background: image-url('home_back.jpg') no-repeat center center; background-size: cover; @@ -671,7 +658,13 @@ label[required]::after{ } .organization-logo { - padding-top: 120px; + padding-top: 80px; + + img { + display: block; + margin: 0 auto; + max-width: 600px; + } } .input__password-eye { diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index b701f070f..689adef37 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -112,8 +112,8 @@ def scoped_users end def user_params - fields_to_permit = %w"gender username email date_of_birth phone - alt_phone active description notifications push_notifications postcode" + fields_to_permit = %w"gender username email date_of_birth phone alt_phone active + locale description notifications push_notifications postcode" fields_to_permit += %w"admin registration_number registration_date" if admin? fields_to_permit += %w"organization_id superadmin" if superadmin? diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index c34d8186b..30d02375d 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -31,7 +31,7 @@ def organization_logo return if "#{controller_name}##{action_name}".in? %w(organizations#index pages#show) content_tag(:div, class: "row organization-logo") do - image_tag(org.logo.variant(resize: "x200^"), class: 'img-responsive center-block') + image_tag org.logo.variant(resize: "x200^") end end diff --git a/app/models/user.rb b/app/models/user.rb index a625c0d09..771dbfeaf 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -31,7 +31,7 @@ class User < ApplicationRecord has_many :device_tokens has_many :petitions, dependent: :delete_all - accepts_nested_attributes_for :members + accepts_nested_attributes_for :members, allow_destroy: true default_scope { order("users.id ASC") } scope :actives, -> { references(:members).where(members: { active: true }) } diff --git a/app/services/user_importer.rb b/app/services/user_importer.rb index e8825dc0a..b75ac273c 100644 --- a/app/services/user_importer.rb +++ b/app/services/user_importer.rb @@ -21,7 +21,8 @@ def user_from_row email: email, phone: phone, alt_phone: alt_phone, - gender: gender + gender: gender, + locale: I18n.locale ) end end diff --git a/app/views/devise/confirmations/new.html.erb b/app/views/devise/confirmations/new.html.erb index 536f86b10..4231f238a 100644 --- a/app/views/devise/confirmations/new.html.erb +++ b/app/views/devise/confirmations/new.html.erb @@ -10,7 +10,7 @@
- email + <%= glyph(:envelope) %> <%= f.text_field :email, required: false, autofocus: true, placeholder: t("application.login_form.email"), class: "form-control input-lg" %>
diff --git a/app/views/devise/passwords/edit.html.erb b/app/views/devise/passwords/edit.html.erb index 84983f571..45ac98b79 100644 --- a/app/views/devise/passwords/edit.html.erb +++ b/app/views/devise/passwords/edit.html.erb @@ -10,7 +10,7 @@
- lock + <%= glyph(:lock) %> <%= f.password_field :password, required: true, autofocus: true, placeholder: t(".new_password"), class: "form-control input-lg" %>
@@ -18,7 +18,7 @@
- lock + <%= glyph(:lock) %> <%= f.password_field :password_confirmation, required: true, placeholder: t(".confirm_password"), oninput: "this.setCustomValidity(this.value != form.user_password.value ? '#{t(".passwords_not_match")}' : '')", class: "form-control input-lg" %>
diff --git a/app/views/devise/passwords/new.html.erb b/app/views/devise/passwords/new.html.erb index fa9c7b616..582464ca9 100644 --- a/app/views/devise/passwords/new.html.erb +++ b/app/views/devise/passwords/new.html.erb @@ -10,7 +10,7 @@
- email + <%= glyph(:envelope) %> <%= f.text_field :email, required: false, autofocus: true, placeholder: t("application.login_form.email"), class: "form-control input-lg" %>
diff --git a/app/views/devise/sessions/new.html.erb b/app/views/devise/sessions/new.html.erb index 6fcd5c7c2..35673c42e 100644 --- a/app/views/devise/sessions/new.html.erb +++ b/app/views/devise/sessions/new.html.erb @@ -8,7 +8,7 @@
- email + <%= glyph(:envelope) %> <%= f.text_field :email, required: false, autofocus: true, placeholder: t("application.login_form.email"), class: "form-control input-lg" %>
@@ -16,11 +16,11 @@
- lock + <%= glyph(:lock) %> <%= f.password_field :password, required: false, autofocus: true, placeholder: t("application.login_form.password"), class: "form-control input-lg" %> - visibility + <%= glyph(:eye_close) %>
diff --git a/app/views/devise/unlocks/new.html.erb b/app/views/devise/unlocks/new.html.erb index b489a6a60..7dd14d1da 100644 --- a/app/views/devise/unlocks/new.html.erb +++ b/app/views/devise/unlocks/new.html.erb @@ -10,7 +10,7 @@
- email + <%= glyph(:envelope) %> <%= f.text_field :email, required: false, autofocus: true, placeholder: t("application.login_form.email"), class: "form-control input-lg" %>
diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index 41e21caf0..1fc53ee74 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -9,7 +9,6 @@ <%= stylesheet_link_tag 'application', media: 'all' %> <%= stylesheet_link_tag 'https://fonts.googleapis.com/css?family=Work+Sans:400,500,600,700' %> - <%= stylesheet_link_tag 'https://fonts.googleapis.com/icon?family=Material+Icons' %> <%= javascript_include_tag 'libs' %> <%= javascript_include_tag 'application' %> diff --git a/app/views/pages/about.html.erb b/app/views/pages/about.html.erb index 5fcf22e96..60698e062 100644 --- a/app/views/pages/about.html.erb +++ b/app/views/pages/about.html.erb @@ -17,7 +17,7 @@ <% for j in 1..3 %>
  • >
    -
    done
    +
    <%= glyph(:ok) %>
    <%= t("pages.about.feature-text-#{i*j}") %>
  • diff --git a/app/views/users/_form.html.erb b/app/views/users/_form.html.erb index f7d6d9328..56118ff56 100644 --- a/app/views/users/_form.html.erb +++ b/app/views/users/_form.html.erb @@ -1,5 +1,7 @@ <%= show_error_messages!(@user) %> <%= simple_form_for @user do |f| %> + <%= f.hidden_field :locale, value: I18n.locale %> +
    <%= f.input :username %> @@ -18,7 +20,7 @@
    - visibility + <%= glyph(:eye_close) %>
    diff --git a/config/initializers/active_admin.rb b/config/initializers/active_admin.rb index e84397b52..135f86fa6 100644 --- a/config/initializers/active_admin.rb +++ b/config/initializers/active_admin.rb @@ -11,12 +11,12 @@ config.comments = false config.namespace :admin do |admin| admin.build_menu :utility_navigation do |menu| - menu.add label: "Languages" do |lang| + menu.add id: :languages, label: -> { "Languages (#{I18n.t("locales.#{locale}")})" } do |lang| I18n.available_locales.each do |locale| lang.add label: I18n.t("locales.#{locale}", locale: locale), url: ->{ url_for(locale: locale) } end end - admin.add_current_user_to_menu menu + admin.add_current_user_to_menu menu admin.add_logout_button_to_menu menu end end diff --git a/spec/services/user_importer_spec.rb b/spec/services/user_importer_spec.rb index b8b9ad17e..e95d69a54 100644 --- a/spec/services/user_importer_spec.rb +++ b/spec/services/user_importer_spec.rb @@ -16,6 +16,8 @@ let(:csv_data) { StringIO.new('1,2018-01-30,Hermione,Cadena,Muñoz,1,1989-03-16,622743103,691777984,user@example.com') } before do + I18n.locale = :en + allow(Organization) .to receive(:find).with(organization.id).and_return(organization) @@ -25,7 +27,8 @@ email: 'user@example.com', phone: '622743103', alt_phone: '691777984', - gender: 'female' + gender: 'female', + locale: :en ).and_return(user) end @@ -36,7 +39,8 @@ email: 'user@example.com', phone: '622743103', alt_phone: '691777984', - gender: 'female' + gender: 'female', + locale: :en ).and_return(user) described_class.call(organization.id, csv_data)