diff --git a/.codecov.yml b/.codecov.yml
index db247200..9c6a4c0d 100644
--- a/.codecov.yml
+++ b/.codecov.yml
@@ -1 +1,6 @@
+coverage:
+ status:
+ project:
+ default:
+ threshold: 0.5%
comment: off
diff --git a/.github/workflows/spec.yml b/.github/workflows/spec.yml
new file mode 100644
index 00000000..87aceb78
--- /dev/null
+++ b/.github/workflows/spec.yml
@@ -0,0 +1,51 @@
+name: Specs
+
+on:
+ push:
+ branches: [ master ]
+ pull_request:
+ branches: [ master ]
+ workflow_dispatch:
+
+jobs:
+ linters:
+ runs-on: ubuntu-latest
+ env:
+ OSEM_RUBY_VERSION: 2.6.6
+ steps:
+ - uses: actions/checkout@v2
+ - uses: ruby/setup-ruby@v1
+ with:
+ ruby-version: 2.6
+ bundler-cache: true
+ - run: bundle exec rubocop
+ - run: bundle exec haml-lint app/views
+ spec:
+ runs-on: ubuntu-latest
+ name: spec
+ env:
+ OSEM_DB_ADAPTER: sqlite3
+ OSEM_RUBY_VERSION: 2.6.6
+ RAILS_ENV: test
+ strategy:
+ matrix:
+ suite: [models, features, controllers, ability, leftovers]
+ steps:
+ - uses: actions/checkout@v2
+ - uses: ruby/setup-ruby@v1
+ with:
+ ruby-version: 2.6
+ bundler-cache: true
+ - name: Prepare spec
+ run: |
+ rm -f osem_test osem_development
+ bundle exec rake db:setup --trace
+ bundle exec bin/rails webdrivers:chromedriver:update
+ - name: spec/${{ matrix.suite }}
+ run: bundle exec rake spec:${{ matrix.suite }}
+ - name: coverage upload ${{ matrix.suite }}
+ uses: codacy/codacy-coverage-reporter-action@master
+ if: github.ref == 'refs/heads/master'
+ with:
+ project-token: ${{ secrets.CODACY_PROJECT_TOKEN }}
+ coverage-reports: coverage/coverage.xml
diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml
index 958943c2..1d036d75 100644
--- a/.rubocop_todo.yml
+++ b/.rubocop_todo.yml
@@ -434,7 +434,7 @@ Metrics/BlockNesting:
# Offense count: 13
# Configuration parameters: CountComments.
Metrics/ClassLength:
- Max: 650
+ Max: 652
# Offense count: 33
Metrics/CyclomaticComplexity:
diff --git a/.travis.yml b/.travis.yml
index a94c68ef..b35784c6 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,21 +1,8 @@
-language: ruby
-cache: bundler
-rvm:
- - 2.6.6
+os: linux
dist: bionic
-addons:
- apt:
- packages:
- - chromium-browser
-services:
- - postgresql
branches:
except:
- /^depfu/.*$/
-before_install:
- - "echo 'gem: --no-ri --no-rdoc' > ~/.gemrc"
- - gem uninstall -v '>= 2' -i $(rvm gemdir)@global -ax bundler || true
- - gem install bundler -v $(tail -n 1 Gemfile.lock)
notifications:
email:
on_success: change
@@ -25,22 +12,9 @@ notifications:
- "chat.freenode.net#osem"
on_success: change
on_failure: change
-before_script:
- # install CodeClimate test reporter and tell it we are starting a test run
- # - curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > $CCTR
- # - chmod +x $CCTR
- # - $CCTR before-build
- - RAILS_ENV=test bundle exec rake db:bootstrap --trace
- - RAILS_ENV=test bundle exec bin/rails webdrivers:chromedriver:update
-script:
- - "bin/travis_script.sh $TEST_SUITE"
- # TODO Get this working.
- # - $CCTR format-coverage -t simplecov --output coverage/codeclimate.$SUITE.json
-# after_script:
- # combine coverage from all suites, and upload3 to CodeClimate
- # - $CCTR sum-coverage coverage/codeclimate.*.json | $CCTR upload-coverage
- # - $CCTR after-build --exit-code $TRAVIS_TEST_RESULT
-
+stages:
+ - test
+ - finalize
env:
global:
- OSEM_DB_ADAPTER=sqlite3
@@ -49,11 +23,90 @@ env:
- OSEM_DB_NAME='osem_test'
- CC_TEST_REPORTER_ID=$CC_TEST_REPORTER
- CCTR=./cc-test-reporter
- matrix:
- - TEST_SUITE=ability
- - TEST_SUITE=features
- - TEST_SUITE=models
- - TEST_SUITE=controllers
- - TEST_SUITE=rest
-matrix:
- fast_finish: false
+ - TOTAL_TEST_SUITES=5
+jobs:
+ include:
+ - &tests
+ language: ruby
+ cache: bundler
+ rvm:
+ - 2.6.6
+ addons:
+ apt:
+ packages:
+ - chromium-browser
+ services:
+ - postgresql
+ before_install:
+ - "echo 'gem: --no-ri --no-rdoc' > ~/.gemrc"
+ - gem uninstall -v '>= 2' -i $(rvm gemdir)@global -ax bundler || true
+ - gem install bundler -v $(tail -n 1 Gemfile.lock)
+ - curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > $CCTR
+ - chmod +x $CCTR
+ before_script:
+ - RAILS_ENV=test bundle exec rake db:bootstrap --trace
+ - RAILS_ENV=test bundle exec bin/rails webdrivers:chromedriver:update
+ - $CCTR before-build
+ script:
+ - "bin/travis_script.sh $TEST_SUITE && $CCTR format-coverage -t cobertura -o ./coverage/codeclimate.1.json ./coverage/coverage.xml"
+ env:
+ - TEST_SUITE=ability
+ workspaces:
+ create:
+ name: ws1
+ paths:
+ - coverage/codeclimate.1.json
+ - <<: *tests
+ env:
+ - TEST_SUITE=features
+ script:
+ - "bin/travis_script.sh $TEST_SUITE && $CCTR format-coverage -t cobertura -o ./coverage/codeclimate.2.json ./coverage/coverage.xml"
+ workspaces:
+ create:
+ name: ws2
+ paths:
+ - coverage/codeclimate.2.json
+ - <<: *tests
+ env:
+ - TEST_SUITE=models
+ script:
+ - "bin/travis_script.sh $TEST_SUITE && $CCTR format-coverage -t cobertura -o ./coverage/codeclimate.3.json ./coverage/coverage.xml"
+ workspaces:
+ create:
+ name: ws3
+ paths:
+ - coverage/codeclimate.3.json
+ - <<: *tests
+ env:
+ - TEST_SUITE=controllers
+ script:
+ - "bin/travis_script.sh $TEST_SUITE && $CCTR format-coverage -t cobertura -o ./coverage/codeclimate.4.json ./coverage/coverage.xml"
+ workspaces:
+ create:
+ name: ws4
+ paths:
+ - coverage/codeclimate.4.json
+ - <<: *tests
+ env:
+ - TEST_SUITE=rest
+ script:
+ - "bin/travis_script.sh $TEST_SUITE && $CCTR format-coverage -t cobertura -o ./coverage/codeclimate.5.json ./coverage/coverage.xml"
+ workspaces:
+ create:
+ name: ws5
+ paths:
+ - coverage/codeclimate.5.json
+ - stage: finalize
+ if: branch = master
+ language: minimal
+ before_install:
+ - curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > $CCTR
+ - chmod +x $CCTR
+ workspaces:
+ use:
+ - ws1
+ - ws2
+ - ws3
+ - ws4
+ - ws5
+ script: $CCTR sum-coverage --output - --parts $TOTAL_TEST_SUITES coverage/codeclimate.*.json | $CCTR upload-coverage --input -
diff --git a/CHANGES.md b/CHANGES.md
index 432cdcdf..0080f621 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -43,8 +43,8 @@ bundle exec rake data:set_conference_in_versions RAILS_ENV=production
### Organization admins
-We have a new role `organization admins` which allow a user to manage his the
-organization and create and manage conference within the organization. This
+We have a new role `organization admins` which allow a user to manage their
+organization and create and manage a conference within the organization. This
needs the role to exist in the database, otherwise the application crashes
as it is assumed to exist. For that, run the following rake task:
diff --git a/Dockerfile b/Dockerfile
index 0b36037d..5a6e7cf1 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,4 +1,4 @@
-FROM osem/base
+FROM registry.opensuse.org/opensuse/infrastructure/osem/containers/osem/base:latest
ARG CONTAINER_USERID
# Configure our user
@@ -16,6 +16,8 @@ RUN chown -R osem /osem
USER osem
WORKDIR /osem/
+# Install bundler & foreman
+RUN sudo gem install bundler:1.17.3 foreman
# Install our bundle
RUN export NOKOGIRI_USE_SYSTEM_LIBRARIES=1; bundle install --jobs=3 --retry=3
diff --git a/Dockerfile.base b/Dockerfile.base
deleted file mode 100644
index 1865285a..00000000
--- a/Dockerfile.base
+++ /dev/null
@@ -1,35 +0,0 @@
-FROM opensuse/leap:15
-
-# Install our requirements
-RUN zypper -n install --no-recommends \
- # for compiling assets/gems
- nodejs8 gcc-c++ git-core make \
- # for ...
- ImageMagick \
- # for bundler
- sudo \
- # as databases
- libmariadb-devel postgresql-devel sqlite3-devel \
- # for nokogiri
- libxml2-devel libxslt-devel \
- # for the interactive shell
- ack curl wget w3m vim which \
- # as ruby
- ruby2.5-devel \
- # as browser for feature tests
- chromium xorg-x11-fonts
-
-# Setup sudo
-RUN echo 'osem ALL=(ALL) NOPASSWD: ALL' >> /etc/sudoers
-
-# Disable versioned gem binary names
-RUN echo 'install: --no-format-executable' >> /etc/gemrc
-
-# Install bundler & foreman
-RUN gem install bundler:1.17.3 foreman
-
-# Create our user
-RUN useradd -m --user-group osem
-
-CMD ["/bin/bash", "-l"]
-
diff --git a/Dockerfile.production b/Dockerfile.production
index 12582dd9..ded47832 100644
--- a/Dockerfile.production
+++ b/Dockerfile.production
@@ -1,4 +1,4 @@
-FROM osem/base
+FROM opensuse/infrastructure/osem/containers/osem/base
# Add our files
COPY --chown=1000:1000 . /osem/
diff --git a/Gemfile b/Gemfile
index 3bca5dfc..87a01972 100644
--- a/Gemfile
+++ b/Gemfile
@@ -157,9 +157,6 @@ gem 'font-awesome-rails'
# for markdown
gem 'redcarpet'
-# as rdoc generator
-gem 'rdoc-generator-fivefish'
-
# for visitor tracking
gem 'piwik_analytics', '~> 1.0.1'
@@ -221,6 +218,8 @@ gem 'nokogiri', '>= 1.8.1'
# memcached binary connector
gem 'dalli'
+gem 'icalendar'
+
# Use guard and spring for testing in development
group :development do
# to launch specs when files are modified
@@ -234,8 +233,6 @@ group :development do
gem 'mina'
# as debugger on error pages
gem 'web-console'
- # as development database
- gem 'sqlite3'
# prepend models with db schema
gem 'annotate'
end
@@ -248,7 +245,7 @@ group :test do
gem 'rspec-rails'
gem 'webdrivers'
# for measuring test coverage
- gem 'codecov', require: false
+ gem 'simplecov-cobertura'
# for describing models
gem 'shoulda-matchers', require: false
# for stubing/mocking models
@@ -273,6 +270,7 @@ group :development, :test, :linters do
# as debugger
gem 'byebug'
gem 'pry'
+ gem 'pry-byebug'
# Linters and static analysis.
gem 'pronto', require: false
@@ -283,3 +281,8 @@ group :development, :test, :linters do
gem 'haml-lint', require: false
end
+
+group :development, :test do
+ # as development/test database
+ gem 'sqlite3'
+end
diff --git a/Gemfile.lock b/Gemfile.lock
index b07d289e..c59eb26c 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -36,9 +36,9 @@ GEM
erubi (~> 1.4)
rails-dom-testing (~> 2.0)
rails-html-sanitizer (~> 1.0, >= 1.0.3)
- active_model_serializers (0.10.10)
- actionpack (>= 4.1, < 6.1)
- activemodel (>= 4.1, < 6.1)
+ active_model_serializers (0.10.12)
+ actionpack (>= 4.1, < 6.2)
+ activemodel (>= 4.1, < 6.2)
case_transform (>= 0.2)
jsonapi-renderer (>= 0.1.1.beta1, < 0.3)
activejob (5.2.4.5)
@@ -79,13 +79,13 @@ GEM
ast (2.4.0)
autoprefixer-rails (9.6.4)
execjs
- awesome_nested_set (3.2.1)
+ awesome_nested_set (3.4.0)
activerecord (>= 4.0.0, < 7.0)
aws_cf_signer (0.1.3)
axlsx_rails (0.5.2)
actionpack (>= 3.1)
axlsx (>= 2.0.1)
- bcrypt (3.1.13)
+ bcrypt (3.1.16)
bindex (0.6.0)
bootstrap-sass (3.4.1)
autoprefixer-rails (>= 5.2.1)
@@ -104,7 +104,7 @@ GEM
rack-test (>= 0.6.3)
regexp_parser (~> 1.5)
xpath (~> 3.2)
- carrierwave (2.2.0)
+ carrierwave (2.1.1)
activemodel (>= 5.0.0)
activesupport (>= 5.0.0)
addressable (~> 2.6)
@@ -126,9 +126,7 @@ GEM
cloudinary (1.11.1)
aws_cf_signer
rest-client
- cocoon (1.2.14)
- codecov (0.5.0)
- simplecov (>= 0.15, < 0.22)
+ cocoon (1.2.15)
coderay (1.1.1)
concurrent-ruby (1.1.8)
countable-rails (0.0.1)
@@ -144,15 +142,15 @@ GEM
safe_yaml (~> 1.0.0)
crass (1.0.6)
daemons (1.3.1)
- dalli (2.7.10)
+ dalli (2.7.11)
dante (0.2.0)
database_cleaner (1.7.0)
- delayed_job (4.1.8)
- activesupport (>= 3.0, < 6.1)
- delayed_job_active_record (4.1.4)
- activerecord (>= 3.0, < 6.1)
+ delayed_job (4.1.9)
+ activesupport (>= 3.0, < 6.2)
+ delayed_job_active_record (4.1.5)
+ activerecord (>= 3.0, < 6.2)
delayed_job (>= 3.0, < 5)
- devise (4.7.1)
+ devise (4.7.3)
bcrypt (~> 3.0)
orm_adapter (~> 0.1)
railties (>= 4.1.0)
@@ -164,10 +162,10 @@ GEM
docile (1.3.5)
domain_name (0.5.20180417)
unf (>= 0.0.5, < 1.0.0)
- dotenv (2.7.5)
- dotenv-rails (2.7.5)
- dotenv (= 2.7.5)
- railties (>= 3.2, < 6.1)
+ dotenv (2.7.6)
+ dotenv-rails (2.7.6)
+ dotenv (= 2.7.6)
+ railties (>= 3.2)
erubi (1.10.0)
erubis (2.7.0)
execjs (2.7.0)
@@ -191,8 +189,8 @@ GEM
path_expander (~> 1.0)
ruby_parser (~> 3.0)
sexp_processor (~> 4.0)
- font-awesome-rails (4.7.0.5)
- railties (>= 3.2, < 6.1)
+ font-awesome-rails (4.7.0.7)
+ railties (>= 3.2, < 7)
formatador (0.2.5)
formtastic (3.1.5)
actionpack (>= 3.2.13)
@@ -254,11 +252,12 @@ GEM
i18n (1.8.9)
concurrent-ruby (~> 1.0)
i18n_data (0.8.0)
+ icalendar (2.7.0)
+ ice_cube (~> 0.16)
+ ice_cube (0.16.3)
image_processing (1.12.1)
mini_magick (>= 4.9.5, < 5)
ruby-vips (>= 2.0.17, < 3)
- inversion (1.1.1)
- loggability (~> 0.12)
io-like (0.3.0)
iso-639 (0.2.8)
jaro_winkler (1.5.3)
@@ -288,7 +287,6 @@ GEM
rb-fsevent (~> 0.9, >= 0.9.4)
rb-inotify (~> 0.9, >= 0.9.7)
ruby_dep (~> 1.2)
- loggability (0.14.0)
loofah (2.9.0)
crass (~> 1.0.2)
nokogiri (>= 1.5.9)
@@ -300,7 +298,7 @@ GEM
method_source (0.8.2)
mime-types (3.3.1)
mime-types-data (~> 3.2015)
- mime-types-data (3.2021.0212)
+ mime-types-data (3.2021.0225)
mimemagic (0.3.5)
mina (1.2.3)
open4 (~> 1.3.4)
@@ -325,7 +323,7 @@ GEM
multipart-post (2.1.1)
nenv (0.3.0)
netrc (0.11.0)
- nio4r (2.5.5)
+ nio4r (2.5.7)
nokogiri (1.11.1)
mini_portile2 (~> 2.5.0)
racc (~> 1.4)
@@ -371,7 +369,7 @@ GEM
parser (2.6.5.0)
ast (~> 2.4.0)
path_expander (1.1.0)
- pdf-core (0.7.0)
+ pdf-core (0.9.0)
pdf-inspector (1.3.0)
pdf-reader (>= 1.0, < 3.0.a)
pdf-reader (2.2.0)
@@ -380,18 +378,18 @@ GEM
hashery (~> 2.0)
ruby-rc4
ttfunk
- pg (1.1.4)
+ pg (1.2.3)
piwik_analytics (1.0.2)
actionpack
activesupport
rails (>= 3.0.0)
- prawn (2.2.2)
- pdf-core (~> 0.7.0)
- ttfunk (~> 1.5)
+ prawn (2.4.0)
+ pdf-core (~> 0.9.0)
+ ttfunk (~> 1.7)
prawn-qrcode (0.3.1)
prawn (>= 1)
rqrcode (>= 0.4.1)
- prawn-rails (1.2.0)
+ prawn-rails (1.3.0)
prawn
prawn-table
rails (>= 3.1.0)
@@ -419,8 +417,11 @@ GEM
coderay (~> 1.1.0)
method_source (~> 0.8.1)
slop (~> 3.4)
+ pry-byebug (3.8.0)
+ byebug (~> 11.0)
+ pry (~> 0.10)
public_suffix (3.1.1)
- puma (5.2.1)
+ puma (5.2.2)
nio4r (~> 2.0)
racc (1.5.2)
rack (2.2.3)
@@ -462,10 +463,10 @@ GEM
rails-assets-to-markdown (3.1.1)
rails-assets-trianglify (1.2.0)
rails-assets-waypoints (4.0.0)
- rails-controller-testing (1.0.4)
- actionpack (>= 5.0.1.x)
- actionview (>= 5.0.1.x)
- activesupport (>= 5.0.1.x)
+ rails-controller-testing (1.0.5)
+ actionpack (>= 5.0.1.rc1)
+ actionview (>= 5.0.1.rc1)
+ activesupport (>= 5.0.1.rc1)
rails-dom-testing (2.0.3)
activesupport (>= 4.2.0)
nokogiri (>= 1.6)
@@ -485,12 +486,6 @@ GEM
rb-fsevent (0.10.3)
rb-inotify (0.10.0)
ffi (~> 1.0)
- rdoc (6.0.4)
- rdoc-generator-fivefish (0.4.0)
- inversion (~> 1.1)
- loggability (~> 0.12)
- rdoc (~> 6.0)
- yajl-ruby (~> 1.3)
recaptcha (4.14.0)
json
redcarpet (3.5.1)
@@ -596,6 +591,8 @@ GEM
docile (~> 1.1)
simplecov-html (~> 0.11)
simplecov_json_formatter (~> 0.1)
+ simplecov-cobertura (1.4.2)
+ simplecov (~> 0.8)
simplecov-html (0.12.3)
simplecov_json_formatter (0.1.2)
sixarm_ruby_unaccent (1.2.0)
@@ -632,7 +629,7 @@ GEM
tilt (2.0.9)
timecop (0.9.1)
transitions (1.2.1)
- ttfunk (1.5.1)
+ ttfunk (1.7.0)
turbolinks (5.2.1)
turbolinks-source (~> 5.2)
turbolinks-source (5.2.0)
@@ -647,8 +644,8 @@ GEM
unicode_utils (1.4.0)
unobtrusive_flash (3.3.1)
railties
- warden (1.2.8)
- rack (>= 2.0.6)
+ warden (1.2.9)
+ rack (>= 2.0.9)
web-console (3.7.0)
actionview (>= 5.0)
activemodel (>= 5.0)
@@ -669,7 +666,6 @@ GEM
chronic (>= 0.6.3)
xpath (3.2.0)
nokogiri (~> 1.8)
- yajl-ruby (1.4.1)
PLATFORMS
ruby
@@ -696,7 +692,6 @@ DEPENDENCIES
climate_control
cloudinary
cocoon
- codecov
countable-rails
country_select
daemons
@@ -717,6 +712,7 @@ DEPENDENCIES
guard-rspec
haml-lint
haml-rails
+ icalendar
iso-639
jquery-datatables
jquery-rails
@@ -746,6 +742,7 @@ DEPENDENCIES
pronto-haml
pronto-rubocop
pry
+ pry-byebug
puma (~> 5.2)
rails (~> 5.2)
rails-assets-bootstrap-markdown!
@@ -762,7 +759,6 @@ DEPENDENCIES
rails-assets-waypoints!
rails-controller-testing
rails-i18n
- rdoc-generator-fivefish
recaptcha
redcarpet
responders (~> 2.0)
@@ -778,6 +774,7 @@ DEPENDENCIES
sentry-rails
sentry-ruby
shoulda-matchers
+ simplecov-cobertura
skylight
spring-commands-rspec
sprockets-rails
diff --git a/README.md b/README.md
index 71f3ac37..1a549b45 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,7 @@
### Spring 2021 Student Project
[](https://travis-ci.com/CactusPuppy/snapcon)
[](https://codeclimate.com/github/CactusPuppy/snapcon/maintainability)
-[](https://codecov.io/gh/CactusPuppy/snapcon)
+[](https://codeclimate.com/github/CactusPuppy/snapcon/test_coverage)
[](https://hakiri.io/github/CactusPuppy/snapcon/master)
[](https://depfu.com/github/CactusPuppy/snapcon?project_id=22682)
[](http://dashboard.bluejay.governify.io/dashboard/script/dashboardLoader.js?dashboardURL=https://reporter.bluejay.governify.io/api/v4/dashboards/tpa-CS169L-GH-CactusPuppy_snapcon/main)
diff --git a/app/assets/images/snapcon_logo.png b/app/assets/images/snapcon_logo.png
index 3d9b05b1..17f3a334 100644
Binary files a/app/assets/images/snapcon_logo.png and b/app/assets/images/snapcon_logo.png differ
diff --git a/app/assets/images/snapshot-2020.png b/app/assets/images/snapshot-2020.png
new file mode 100644
index 00000000..3d9b05b1
Binary files /dev/null and b/app/assets/images/snapshot-2020.png differ
diff --git a/app/assets/javascripts/osem-datepickers.js b/app/assets/javascripts/osem-datepickers.js
index 8b808b63..e5bbe10e 100644
--- a/app/assets/javascripts/osem-datepickers.js
+++ b/app/assets/javascripts/osem-datepickers.js
@@ -13,11 +13,13 @@ $(function () {
$("#conference-start-datepicker").datetimepicker({
useCurrent: false,
- format: "YYYY-MM-DD"
+ ignoreReadonly: true,
+ format: "YYYY-MM-DD",
});
$("#conference-end-datepicker").datetimepicker({
useCurrent: false,
+ ignoreReadonly: true,
format: "YYYY-MM-DD"
});
diff --git a/app/assets/javascripts/osem.js b/app/assets/javascripts/osem.js
index 0839f13b..c4c8356a 100644
--- a/app/assets/javascripts/osem.js
+++ b/app/assets/javascripts/osem.js
@@ -49,6 +49,8 @@ $(function () {
$('.' + id).collapse('hide');
$('#' + $(this).val() + '-help.' + id).collapse('show');
+ $('#' + $(this).val() + '-instructions.' + id).collapse('show');
+
});
$('.dropdown-toggle').dropdown();
@@ -147,6 +149,15 @@ function word_count(text, divId, maxcount) {
});
};
+function fill_if_empty(text_area, filler) {
+ let area = $('#' + text_area);
+
+ if (!area.val()) {
+ area.val(filler);
+ area.trigger('change');
+ }
+}
+
/* Wait for the DOM to be ready before attaching events to the elements */
$( document ).ready(function() {
/* Set the minimum and maximum proposal abstract and submission text word length */
@@ -155,17 +166,16 @@ $( document ).ready(function() {
var max = $selected.data("max-words");
var min = $selected.data("min-words");
+ // Set the filler text for the submission text
+ fill_if_empty('event_submission_text', $selected.data("instructions"));
+
$("#abstract-maximum-word-count").text(max);
$("#submission-maximum-word-count").text(max);
$("#abstract-minimum-word-count").text(min);
$("#submission-minimum-word-count").text(min);
word_count($('#event_abstract').get(0), 'abstract-count', max);
word_count($('#event_submission_text').get(0), 'submission-count', max);
-
- // Set the placeholder text for the abstract
- $('#event_submission_text').attr("placeholder", $selected.data("help"));
- })
- .trigger('change');
+ }).trigger('change');
/* Count the proposal abstract length */
$("#event_abstract").bind('change keyup paste input', function() {
@@ -180,6 +190,18 @@ $( document ).ready(function() {
var max = $selected.data("max-words");
word_count(this, 'submission-count', max);
});
+
+ /* Listen for reset template button, wait for confirm, and reset. */
+ $('.js-resetSubmissionText').click((e) => {
+ let $selected = $("#event_event_type_id option:selected");
+ let $this = $(e.target);
+ let affirm = confirm($this.data('confirm'));
+ if (affirm) {
+ let sub_text = $('#event_submission_text');
+ sub_text.val($selected.data('instructions'));
+ sub_text.trigger('change');
+ }
+ });
});
/* Commodity function for modal windows */
diff --git a/app/assets/stylesheets/mailbot.css b/app/assets/stylesheets/mailbot.css
new file mode 100644
index 00000000..870eb7ef
--- /dev/null
+++ b/app/assets/stylesheets/mailbot.css
@@ -0,0 +1,40 @@
+html {
+ scroll-behavior: smooth;
+ }
+
+ body {
+ background: #fff;
+ box-shadow: 0 0 2px rgba(0, 0, 0, 0.06);
+ color: #000;
+ font-family: 'Montserrat', sans-serif;
+ font-size: 16px;
+ line-height: 1.5;
+ margin: 0 auto;
+ }
+
+ h1,
+ h3,
+ h4,
+ h5,
+ h6 {
+ font-weight: 400;
+ line-height: 1.3;
+ }
+ p {
+ color: #0B3559;
+ font-weight: 400;
+ line-height: 2;
+ }
+
+ #border {
+ background-color: #0B3559;
+ padding: 25px;
+ color:#fff;
+ }
+
+ #content {
+ background-color: #fff;
+ padding: 100px;
+ color: #0B3559;
+ }
+
\ No newline at end of file
diff --git a/app/assets/stylesheets/osem-dashboard.scss b/app/assets/stylesheets/osem-dashboard.scss
index 3b5685ad..24c60a27 100644
--- a/app/assets/stylesheets/osem-dashboard.scss
+++ b/app/assets/stylesheets/osem-dashboard.scss
@@ -1,26 +1,34 @@
@import "breakpoints.scss";
.dashbox span.fa {
- line-height: 1.1em;
+ margin-bottom: 2px;
+
+ @include breakpoint(xs) {
+ font-size: 1.5em;
+ }
@include breakpoint(sm) {
- font-size: 3em;
+ font-size: 2em;
}
@include breakpoint(md) {
- font-size: 4em;
+ font-size: 3.5em;
}
@include breakpoint(lg) {
font-size: 5em;
}
}
-.dashbox {
- padding-top: 20px;
- padding-bottom: 20px;
-}
+.dashbox.panel {
+ padding: 10px;
+ display: -webkit-flex;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ font-size: 1.4rem;
+ line-height: 1.6rem;
-.dashbox label {
- display: block;
- font-size: 1.1em;
+ label {
+ line-height: 2rem;
+ }
}
.todolist-missing span {
diff --git a/app/controllers/admin/conferences_controller.rb b/app/controllers/admin/conferences_controller.rb
index dc73df87..1ae78998 100644
--- a/app/controllers/admin/conferences_controller.rb
+++ b/app/controllers/admin/conferences_controller.rb
@@ -124,8 +124,7 @@ module Admin
# current_user.last_sign_in_at
# ).count
- # Step by step list
- # @conference_progress = @conference.get_status
+ @conference_todo_list = @conference.get_status
# Line charts
@registrations = @conference.get_registrations_per_week
diff --git a/app/controllers/admin/event_types_controller.rb b/app/controllers/admin/event_types_controller.rb
index 137e8f00..e7f19863 100644
--- a/app/controllers/admin/event_types_controller.rb
+++ b/app/controllers/admin/event_types_controller.rb
@@ -49,7 +49,7 @@ module Admin
private
def event_type_params
- params.require(:event_type).permit(:title, :length, :minimum_abstract_length, :maximum_abstract_length, :color, :conference_id, :description)
+ params.require(:event_type).permit(:title, :length, :minimum_abstract_length, :maximum_abstract_length, :submission_instructions, :color, :conference_id, :description)
end
end
end
diff --git a/app/controllers/admin/users_controller.rb b/app/controllers/admin/users_controller.rb
index e49c02f5..2eb2032a 100644
--- a/app/controllers/admin/users_controller.rb
+++ b/app/controllers/admin/users_controller.rb
@@ -66,6 +66,16 @@ module Admin
def edit; end
+ def destroy
+ if @user.destroy
+ redirect_to admin_users_path,
+ notice: "User #{@user.id} (#{@user.email}) deleted."
+ else
+ redirect_to admin_users_path,
+ error: "User #{@user.id} (#{@user.emai}) could not be deleted. #{@user.full_messages.join(',')}"
+ end
+ end
+
private
def user_params
diff --git a/app/controllers/conferences_controller.rb b/app/controllers/conferences_controller.rb
index f581e367..02d869f4 100644
--- a/app/controllers/conferences_controller.rb
+++ b/app/controllers/conferences_controller.rb
@@ -6,8 +6,11 @@ class ConferencesController < ApplicationController
load_and_authorize_resource find_by: :short_title, except: :show
def index
- @current = Conference.where('end_date >= ?', Date.current).reorder(start_date: :asc)
- @antiquated = Conference.where('end_date < ?', Date.current)
+ @current = Conference.upcoming.reorder(start_date: :asc)
+ @antiquated = Conference.past
+ if @antiquated.empty? && @current.empty? && User.empty?
+ render :new_install
+ end
end
def show
@@ -68,6 +71,47 @@ class ConferencesController < ApplicationController
end
end
+ def calendar
+ respond_to do |format|
+ format.ics do
+ calendar = Icalendar::Calendar.new
+ Conference.all.each do |conf|
+ if params[:full]
+ event_schedules = conf.program.selected_event_schedules(
+ includes: [{ event: %i[event_type speakers submitter] }]
+ )
+ calendar = icalendar_proposals(calendar, event_schedules.map(&:event), conf)
+ else
+ calendar.event do |e|
+ e.dtstart = conf.start_date
+ e.dtstart.ical_params = { 'VALUE'=>'DATE' }
+ e.dtend = conf.end_date
+ e.dtend.ical_params = { 'VALUE'=>'DATE' }
+ e.duration = "P#{(conf.end_date - conf.start_date + 1).floor}D"
+ e.created = conf.created_at
+ e.last_modified = conf.updated_at
+ e.summary = conf.title
+ e.description = conf.description
+ e.uid = conf.guid
+ e.url = conference_url(conf.short_title)
+ v = conf.venue
+ if v
+ e.geo = v.latitude, v.longitude if v.latitude && v.longitude
+ location = ''
+ location += "#{v.street}, " if v.street
+ location += "#{v.postalcode} #{v.city}, " if v.postalcode && v.city
+ location += v.country_name if v.country_name
+ e.location = location if location
+ end
+ end
+ end
+ end
+ calendar.publish
+ render inline: calendar.to_ical
+ end
+ end
+ end
+
private
def conference_finder_conditions
diff --git a/app/controllers/payments_controller.rb b/app/controllers/payments_controller.rb
index 5dae6d19..ffbfec15 100644
--- a/app/controllers/payments_controller.rb
+++ b/app/controllers/payments_controller.rb
@@ -16,6 +16,7 @@ class PaymentsController < ApplicationController
raise CanCan::AccessDenied.new('Nothing to pay for!', :new, Payment)
end
+ @has_registration_ticket = params[:has_registration_ticket]
@unpaid_ticket_purchases = current_user.ticket_purchases.unpaid.by_conference(@conference)
end
@@ -24,8 +25,15 @@ class PaymentsController < ApplicationController
if @payment.purchase && @payment.save
update_purchased_ticket_purchases
- redirect_to conference_physical_tickets_path,
- notice: 'Thanks! Your ticket is booked successfully.'
+
+ has_registration_ticket = params[:has_registration_ticket]
+ if has_registration_ticket == 'true'
+ redirect_to new_conference_conference_registration_path(@conference.short_title),
+ notice: 'Thanks! Your ticket is booked successfully. Please register for the conference.'
+ else
+ redirect_to conference_physical_tickets_path,
+ notice: 'Thanks! Your ticket is booked successfully.'
+ end
else
@total_amount_to_pay = Ticket.total_price(@conference, current_user, paid: false)
@unpaid_ticket_purchases = current_user.ticket_purchases.unpaid.by_conference(@conference)
diff --git a/app/controllers/schedules_controller.rb b/app/controllers/schedules_controller.rb
index cbff9cc8..230cda2f 100644
--- a/app/controllers/schedules_controller.rb
+++ b/app/controllers/schedules_controller.rb
@@ -21,6 +21,12 @@ class SchedulesController < ApplicationController
format.xml do
@events_xml = event_schedules.map(&:event).group_by{ |event| event.time.to_date } if event_schedules
end
+ format.ics do
+ cal = Icalendar::Calendar.new
+ cal = icalendar_proposals(cal, event_schedules.map(&:event), @conference)
+ cal.publish
+ render inline: cal.to_ical
+ end
format.html do
@rooms = @conference.venue.rooms if @conference.venue
diff --git a/app/controllers/ticket_purchases_controller.rb b/app/controllers/ticket_purchases_controller.rb
index 1a1bc449..3034d742 100644
--- a/app/controllers/ticket_purchases_controller.rb
+++ b/app/controllers/ticket_purchases_controller.rb
@@ -8,23 +8,42 @@ class TicketPurchasesController < ApplicationController
def create
current_user.ticket_purchases.by_conference(@conference).unpaid.destroy_all
+
+ # Create a ticket purchase which can be paid or unpaid
+ count_registration_tickets_before = current_user.count_registration_tickets(@conference)
message = TicketPurchase.purchase(@conference, current_user, params[:tickets].try(:first))
- if message.blank?
- if current_user.ticket_purchases.by_conference(@conference).unpaid.any?
- redirect_to new_conference_payment_path,
- notice: 'Please pay here to get tickets.'
- elsif current_user.ticket_purchases.by_conference(@conference).paid.any?
- redirect_to conference_physical_tickets_path,
- notice: 'You already have tickets for the conference.'
- elsif @conference.tickets.for_registration.any?
- redirect_to conference_tickets_path(@conference.short_title),
- error: 'Please get at least one ticket to continue.'
- else
- redirect_to conference_conference_registration_path(@conference.short_title)
- end
- else
+ # The new ticket_purchase has been added to the database. current_user.ticket_purchases contains the new one.
+ count_registration_tickets_after = current_user.count_registration_tickets(@conference)
+
+ # Failed to create ticket purchase
+ unless message.blank?
redirect_to conference_tickets_path(@conference.short_title),
error: "Oops, something went wrong with your purchase! #{message}"
+ return
+ end
+
+ # Current user already paid for a registration ticket and the current ticket purchase contains one
+ if count_registration_tickets_before == 1 && count_registration_tickets_after > 1
+ redirect_to conference_physical_tickets_path,
+ error: 'You already have one registration ticket for the conference.'
+ return
+ end
+
+ # User needs to pay for tickets if any of them is not free.
+ if current_user.ticket_purchases.by_conference(@conference).unpaid.any?
+ has_registration_ticket = count_registration_tickets_before.zero? && count_registration_tickets_after == 1
+ redirect_to new_conference_payment_path(has_registration_ticket: has_registration_ticket),
+ notice: 'Please pay here to get tickets.'
+ return
+ end
+
+ # Redirect to registration page for a user who didn't have a registration ticket and is purchasing one
+ if count_registration_tickets_before.zero? && count_registration_tickets_after == 1
+ redirect_to new_conference_conference_registration_path(@conference.short_title),
+ notice: 'Thanks! Your ticket is booked successfully. Please register for the conference.'
+ else
+ redirect_to conference_physical_tickets_path,
+ notice: 'Thanks! Your ticket is booked successfully.'
end
end
diff --git a/app/datatables/user_datatable.rb b/app/datatables/user_datatable.rb
index 45200ebb..cc29e995 100644
--- a/app/datatables/user_datatable.rb
+++ b/app/datatables/user_datatable.rb
@@ -35,7 +35,8 @@ class UserDatatable < AjaxDatatablesRails::Base
roles: record.roles.any? ? show_roles(record.get_roles) : 'None',
view_url: admin_user_path(record),
edit_url: edit_admin_user_path(record),
- DT_RowId: record.id
+ DT_RowId: record.id,
+ confirmed: record.confirmed_at.present?
}
end
end
diff --git a/app/helpers/conference_helper.rb b/app/helpers/conference_helper.rb
index 85ead390..417a8d55 100644
--- a/app/helpers/conference_helper.rb
+++ b/app/helpers/conference_helper.rb
@@ -1,5 +1,8 @@
# frozen_string_literal: true
+DEFAULT_LOGO = 'snapcon_logo.png'
+DEFAULT_COLOR = '#0B3559'
+
module ConferenceHelper
# Return true if only call_for_papers or call_for_tracks or call_for_booths is open
def one_call_open(*calls)
@@ -27,4 +30,51 @@ module ConferenceHelper
markdown(ticket.description.split("\n").first&.strip)
end
+
+ def conference_logo_url(conference)
+ if conference.picture.present?
+ conference.picture.thumb.url
+ elsif conference.organization.picture.present?
+ conference.organization.picture.thumb.url
+ else
+ DEFAULT_LOGO
+ end
+ end
+
+ def conference_color(conference)
+ if conference.color.present?
+ conference.color
+ else
+ DEFAULT_COLOR
+ end
+ end
+
+ # adds events to icalendar for proposals in a conference
+ def icalendar_proposals(calendar, proposals, conference)
+ proposals.each do |proposal|
+ calendar.event do |e|
+ e.dtstart = proposal.time
+ e.dtend = proposal.time + proposal.event_type.length * 60
+ e.duration = "PT#{proposal.event_type.length}M"
+ e.created = proposal.created_at
+ e.last_modified = proposal.updated_at
+ e.summary = proposal.title
+ e.description = proposal.abstract
+ e.uid = proposal.guid
+ e.url = conference_program_proposal_url(conference.short_title, proposal.id)
+ v = conference.venue
+ if v
+ e.geo = v.latitude, v.longitude if v.latitude && v.longitude
+ location = ''
+ location += "#{proposal.room.name} - " if proposal.room.name
+ location += " - #{v.street}, " if v.street
+ location += "#{v.postalcode} #{v.city}, " if v.postalcode && v.city
+ location += "#{v.country_name}, " if v.country_name
+ e.location = location
+ end
+ e.categories = conference.title, "Difficulty: #{proposal.difficulty_level.title}", "Track: #{proposal.track.name}"
+ end
+ end
+ calendar
+ end
end
diff --git a/app/helpers/events_helper.rb b/app/helpers/events_helper.rb
index eebaa4fe..eb5cd930 100644
--- a/app/helpers/events_helper.rb
+++ b/app/helpers/events_helper.rb
@@ -60,6 +60,20 @@ module EventsHelper
"#{event.average_rating}/#{max_rating}, #{pluralize(event.voters.length, 'vote')}"
end
+ def event_type_options(event_types)
+ event_types.map do |type|
+ [
+ "#{type.title} - #{show_time(type.length)}",
+ type.id,
+ data: {
+ min_words: type.minimum_abstract_length,
+ max_words: type.maximum_abstract_length,
+ instructions: type.submission_instructions
+ }
+ ]
+ end
+ end
+
def event_type_dropdown(event, event_types, conference_id)
selection = event.event_type.try(:title) || 'Event Type'
options = event_types.collect do |event_type|
diff --git a/app/mailers/mailbot.rb b/app/mailers/mailbot.rb
index c055ec84..2f9d1f77 100644
--- a/app/mailers/mailbot.rb
+++ b/app/mailers/mailbot.rb
@@ -5,21 +5,26 @@ EMAIL_TEMPLATE = 'email_template'
YTLF_TICKET_ID = 50
class Mailbot < ActionMailer::Base
- def registration_mail(conference, user)
- @email_body = conference.email_settings.generate_email_on_conf_updates(conference, user, conference.email_settings.registration_body)
- @logo = conference.picture.thumb.url
+ helper ConferenceHelper
- mail(to: user.email,
- bcc: SNAPCON_BCC_ADDRESS,
- from: conference.contact.email,
- subject: conference.email_settings.registration_subject,
- template_name: EMAIL_TEMPLATE)
+ default bcc: SNAPCON_BCC_ADDRESS,
+ template_name: EMAIL_TEMPLATE,
+ content_type: 'text/html',
+ to: -> { @user.email },
+ from: -> { @conference.contact.email }
+
+ def registration_mail(conference, user)
+ @user = user
+ @conference = conference
+ @email_body = @conference.email_settings.generate_email_on_conf_updates(@conference, @user, @conference.email_settings.registration_body)
+
+ mail(subject: @conference.email_settings.registration_subject)
end
def ticket_confirmation_mail(ticket_purchase)
@ticket_purchase = ticket_purchase
- @conference = ticket_purchase.conference
@user = ticket_purchase.user
+ @conference = ticket_purchase.conference
PhysicalTicket.last(ticket_purchase.quantity).each do |physical_ticket|
pdf = TicketPdf.new(@conference, @user, physical_ticket, @conference.ticket_layout.to_sym, "ticket_for_#{@conference.short_title}_#{physical_ticket.id}")
@@ -31,138 +36,100 @@ class Mailbot < ActionMailer::Base
template_name = 'young_thinkers_ticket_confirmation_template'
end
- mail(to: @user.email,
- bcc: SNAPCON_BCC_ADDRESS,
- from: @conference.contact.email,
- template_name: template_name,
- subject: "#{@conference.title} | Ticket Confirmation and PDF!")
+ mail(subject: "#{@conference.title} | Ticket Confirmation and PDF!",
+ template_name: template_name)
end
def acceptance_mail(event)
- conference = event.program.conference
+ @user = event.submitter
+ @conference = event.program.conference
+ @email_body = @conference.email_settings.generate_event_mail(event, @conference.email_settings.accepted_body)
- @logo = conference.picture.thumb.url
- @email_body = conference.email_settings.generate_event_mail(event, conference.email_settings.accepted_body)
-
- mail(to: event.submitter.email,
- bcc: SNAPCON_BCC_ADDRESS,
- from: conference.contact.email,
- subject: conference.email_settings.accepted_subject,
- template_name: EMAIL_TEMPLATE)
+ mail(subject: @conference.email_settings.accepted_subject)
end
def submitted_proposal_mail(event)
- conference = event.program.conference
+ @user = event.submitter
+ @conference = event.program.conference
+ @email_body = @conference.email_settings.generate_event_mail(event, @conference.email_settings.submitted_proposal_body)
- @logo = conference.picture.thumb.url
- @email_body = conference.email_settings.generate_event_mail(event, conference.email_settings.submitted_proposal_body)
-
- mail(to: event.submitter.email,
- bcc: SNAPCON_BCC_ADDRESS,
- from: conference.contact.email,
- subject: conference.email_settings.submitted_proposal_subject,
- template_name: EMAIL_TEMPLATE)
+ mail(subject: @conference.email_settings.submitted_proposal_subject)
end
def rejection_mail(event)
- conference = event.program.conference
+ @user = event.submitter
+ @conference = event.program.conference
+ @email_body = @conference.email_settings.generate_event_mail(event, @conference.email_settings.rejected_body)
- @logo = conference.picture.thumb.url
- @email_body = conference.email_settings.generate_event_mail(event, conference.email_settings.rejected_body)
-
- mail(to: event.submitter.email,
- bcc: SNAPCON_BCC_ADDRESS,
- from: conference.contact.email,
- subject: conference.email_settings.rejected_subject,
- template_name: EMAIL_TEMPLATE)
+ mail(subject: @conference.email_settings.rejected_subject)
end
def confirm_reminder_mail(event)
- conference = event.program.conference
+ @user = event.submitter
+ @conference = event.program.conference
+ @email_body = @conference.email_settings.generate_event_mail(event, @conference.email_settings.confirmed_without_registration_body)
- @logo = conference.picture.thumb.url
- @email_body = conference.email_settings.generate_event_mail(event, conference.email_settings.confirmed_without_registration_body)
-
- mail(to: event.submitter.email,
- bcc: SNAPCON_BCC_ADDRESS,
- from: conference.contact.email,
- subject: conference.email_settings.confirmed_without_registration_subject,
- template_name: EMAIL_TEMPLATE)
+ mail(subject: @conference.email_settings.confirmed_without_registration_subject)
end
def conference_date_update_mail(conference, user)
- @logo = conference.picture.thumb.url
- @email_body = conference.email_settings.generate_email_on_conf_updates(conference, user, conference.email_settings.conference_dates_updated_body)
+ @user = user
+ @conference = conference
+ @email_body = @conference.email_settings.generate_email_on_conf_updates(@conference, @user, @conference.email_settings.conference_dates_updated_body)
- mail(to: user.email,
- bcc: SNAPCON_BCC_ADDRESS,
- from: conference.contact.email,
- subject: conference.email_settings.conference_dates_updated_subject,
- template_name: EMAIL_TEMPLATE)
+ mail(subject: @conference.email_settings.conference_dates_updated_subject)
end
def conference_registration_date_update_mail(conference, user)
- @logo = conference.picture.thumb.url
- @email_body = conference.email_settings.generate_email_on_conf_updates(conference, user, conference.email_settings.conference_registration_dates_updated_body)
+ @user = user
+ @conference = conference
+ @email_body = @conference.email_settings.generate_email_on_conf_updates(@conference, @user, @conference.email_settings.conference_registration_dates_updated_body)
- mail(to: user.email,
- bcc: SNAPCON_BCC_ADDRESS,
- from: conference.contact.email,
- subject: conference.email_settings.conference_registration_dates_updated_subject,
- template_name: EMAIL_TEMPLATE)
+ mail(subject: @conference.email_settings.conference_registration_dates_updated_subject)
end
def conference_venue_update_mail(conference, user)
- @logo = conference.picture.thumb.url
- @email_body = conference.email_settings.generate_email_on_conf_updates(conference, user, conference.email_settings.venue_updated_body)
+ @user = user
+ @conference = conference
+ @email_body = @conference.email_settings.generate_email_on_conf_updates(@conference, @user, @conference.email_settings.venue_updated_body)
- mail(to: user.email,
- bcc: SNAPCON_BCC_ADDRESS,
- from: conference.contact.email,
- subject: conference.email_settings.venue_updated_subject,
- template_name: EMAIL_TEMPLATE)
+ mail(subject: @conference.email_settings.venue_updated_subject)
end
def conference_schedule_update_mail(conference, user)
- @logo = conference.picture.thumb.url
- @email_body = conference.email_settings.generate_email_on_conf_updates(conference, user, conference.email_settings.program_schedule_public_body)
+ @user = user
+ @conference = conference
+ @email_body = @conference.email_settings.generate_email_on_conf_updates(@conference, @user, @conference.email_settings.program_schedule_public_body)
- mail(to: user.email,
- from: conference.contact.email,
- subject: conference.email_settings.program_schedule_public_subject,
- template_name: EMAIL_TEMPLATE)
+ mail(bcc: nil,
+ subject: @conference.email_settings.program_schedule_public_subject)
end
def conference_cfp_update_mail(conference, user)
- @logo = conference.picture.thumb.url
- @email_body = conference.email_settings.generate_email_on_conf_updates(conference, user, conference.email_settings.cfp_dates_updated_body)
+ @user = user
+ @conference = conference
+ @email_body = @conference.email_settings.generate_email_on_conf_updates(@conference, @user, @conference.email_settings.cfp_dates_updated_body)
- mail(to: user.email,
- from: conference.contact.email,
- subject: conference.email_settings.cfp_dates_updated_subject,
- template_name: EMAIL_TEMPLATE)
+ mail(bcc: nil,
+ subject: @conference.email_settings.cfp_dates_updated_subject)
end
def conference_booths_acceptance_mail(booth)
- conference = booth.conference
- @logo = conference.picture.thumb.url
- @email_body = conference.email_settings.generate_booth_mail(booth, conference.email_settings.booths_acceptance_body)
+ @user = booth.submitter
+ @conference = booth.conference
+ @email_body = @conference.email_settings.generate_booth_mail(booth, @conference.email_settings.booths_acceptance_body)
- mail(to: booth.submitter.email,
- from: conference.contact.email,
- subject: conference.email_settings.booths_acceptance_subject,
- template_name: EMAIL_TEMPLATE)
+ mail(bcc: nil,
+ subject: @conference.email_settings.booths_acceptance_subject)
end
def conference_booths_rejection_mail(booth)
- conference = booth.conference
- @logo = conference.picture.thumb.url
- @email_body = conference.email_settings.generate_booth_mail(booth, conference.email_settings.booths_rejection_body)
+ @user = booth.submitter
+ @conference = booth.conference
+ @email_body = @conference.email_settings.generate_booth_mail(booth, @conference.email_settings.booths_rejection_body)
- mail(to: booth.submitter.email,
- from: conference.contact.email,
- subject: conference.email_settings.booths_rejection_subject,
- template_name: EMAIL_TEMPLATE)
+ mail(bcc: nil,
+ subject: @conference.email_settings.booths_rejection_subject)
end
def event_comment_mail(comment, user)
@@ -171,8 +138,7 @@ class Mailbot < ActionMailer::Base
@conference = @event.program.conference
@user = user
- mail(to: @user.email,
- from: @conference.contact.email,
+ mail(bcc: nil,
template_name: 'comment_template',
subject: "New comment has been posted for #{@event.title}")
end
diff --git a/app/models/conference.rb b/app/models/conference.rb
index 44224ab7..e9a0fa23 100644
--- a/app/models/conference.rb
+++ b/app/models/conference.rb
@@ -61,6 +61,9 @@ class Conference < ApplicationRecord
has_one :email_settings, dependent: :destroy
has_one :program, dependent: :destroy
has_one :venue, dependent: :destroy
+ delegate :city, :country_name, to: :venue, allow_nil: true
+ delegate :name, :street, to: :venue, prefix: true, allow_nil: true
+
has_many :ticket_purchases, dependent: :destroy
has_many :physical_tickets, through: :ticket_purchases
has_many :payments, dependent: :destroy
diff --git a/app/models/event.rb b/app/models/event.rb
index d10ae1a1..b172bc3b 100644
--- a/app/models/event.rb
+++ b/app/models/event.rb
@@ -274,7 +274,7 @@ class Event < ApplicationRecord
biographies: speakers.all? { |speaker| !speaker.biography.blank? },
subtitle: !subtitle.blank?,
track: (!track.blank? unless program.tracks.empty?),
- difficulty_level: !difficulty_level.blank?,
+ difficulty_level: (difficulty_level.present? unless program.difficulty_levels.empty?),
title: true,
abstract: true
}.with_indifferent_access
diff --git a/app/models/event_type.rb b/app/models/event_type.rb
index 67d7fb20..2ef440bc 100644
--- a/app/models/event_type.rb
+++ b/app/models/event_type.rb
@@ -10,6 +10,7 @@
# length :integer default(30)
# maximum_abstract_length :integer default(500)
# minimum_abstract_length :integer default(0)
+# submission_instructions :text
# title :string not null
# created_at :datetime
# updated_at :datetime
diff --git a/app/models/survey_question.rb b/app/models/survey_question.rb
index 6b365236..46c20843 100644
--- a/app/models/survey_question.rb
+++ b/app/models/survey_question.rb
@@ -24,8 +24,8 @@ class SurveyQuestion < ActiveRecord::Base
validates :title, presence: true
validates :possible_answers, :max_choices, :min_choices, presence: true, if: :choice?
- validates :min_choices, numericality: { greater_than_or_equal_to: 1 }, allow_blank: true
- validates :max_choices, numericality: { greater_than_or_equal_to: 1 }, allow_blank: true
+ validates :min_choices, numericality: { greater_than_or_equal_to: 1 }, allow_blank: true, if: :choice?
+ validates :max_choices, numericality: { greater_than_or_equal_to: 1 }, allow_blank: true, if: :choice?
validate :max_choices_greater_than_min
diff --git a/app/models/user.rb b/app/models/user.rb
index 9bd1bf80..955c76d1 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -346,6 +346,17 @@ class User < ApplicationRecord
events.where(program_id: conference.program.id, 'event_users.event_role': 'volunteer')
end
+ def count_registration_tickets(conference)
+ count = 0
+ ticket_purchases.by_conference(conference).each do |ticket_purchase|
+ if ticket_purchase.ticket.registration_ticket
+ count += 1
+ end
+ end
+
+ count
+ end
+
def self.empty?
User.count == 1 && User.first.email == 'deleted@localhost.osem'
end
diff --git a/app/pdfs/ticket_pdf.rb b/app/pdfs/ticket_pdf.rb
index 306d5870..c4408e7c 100644
--- a/app/pdfs/ticket_pdf.rb
+++ b/app/pdfs/ticket_pdf.rb
@@ -69,9 +69,9 @@ class TicketPdf < Prawn::Document
draw_text @conference.title.to_s, at: [@mid_horizontal + 30, cursor - 30], size: 12
draw_text @conference.organization.name.to_s, at: [@mid_horizontal + 30, cursor - 50], size: 12
if @conference.venue
- draw_text @conference.venue.name, at: [@mid_horizontal + 30, cursor - 70]
- draw_text @conference.venue.street, at: [@mid_horizontal + 30, cursor - 90]
- draw_text @conference.venue.city, at: [@mid_horizontal + 30, cursor - 110]
+ draw_text @conference.venue_name, at: [@mid_horizontal + 30, cursor - 70]
+ draw_text @conference.venue_street, at: [@mid_horizontal + 30, cursor - 90]
+ draw_text @conference.city, at: [@mid_horizontal + 30, cursor - 110]
end
move_up 130
move_down @mid_vertical
diff --git a/app/uploaders/picture_uploader.rb b/app/uploaders/picture_uploader.rb
index 47e86f8b..3d7e6edb 100644
--- a/app/uploaders/picture_uploader.rb
+++ b/app/uploaders/picture_uploader.rb
@@ -6,6 +6,8 @@ class PictureUploader < CarrierWave::Uploader::Base
include CarrierWave::Compatibility::Paperclip
include CarrierWave::BombShelter
+ storage :file
+
# use cloudinary if it's configured
if Cloudinary.config.cloud_name
# use https by default
diff --git a/app/views/admin/conferences/_todo_list.html.haml b/app/views/admin/conferences/_todo_list.html.haml
index 88bb7c36..74ddc796 100644
--- a/app/views/admin/conferences/_todo_list.html.haml
+++ b/app/views/admin/conferences/_todo_list.html.haml
@@ -1,13 +1,14 @@
-.list-group
- %li{ 'class' => "list-group-item #{hidden_if_conference_over(conference)}" }
+%ul.list-group
+ .list-group-item
%h4
Conference progress
.progress
- .progress-bar{ 'role' => 'progressbar', 'aria-valuenow' => "#{conference_progress['process']}", 'aria-valuemin' => '0',
- 'aria-valuemax' => '100', 'style' => "width: #{conference_progress['process']}%;" }
+ .progress-bar{ role: 'progressbar', 'aria-valuenow': conference_progress['process'],
+ 'aria-valuemin': 0, 'aria-valuemax': 100,
+ style: "width: #{conference_progress['process']}%;" }
= conference_progress['process'] + '%'
- %li{ 'class' => "list-group-item #{hidden_if_conference_over(conference)} #{class_for_todo(conference_progress['registration'])}" }
- %span{ 'class' => icon_for_todo(conference_progress['registration']) }
+ %li.list-group-item{ class: class_for_todo(conference_progress['registration']) }
+ %span{ class: icon_for_todo(conference_progress['registration']) }
- if can? :update, @conference
- if conference.registration_period
= link_to 'Set up registration period', edit_admin_conference_registration_period_path(conference_progress['short_title'])
@@ -15,14 +16,14 @@
= link_to 'Set up registration period', new_admin_conference_registration_period_path(conference_progress['short_title'])
- else
Set up registration period
- %li{ 'class' => "list-group-item #{hidden_if_conference_over(conference)} #{class_for_todo(conference_progress['cfp'])}" }
- %span{ 'class' => icon_for_todo(conference_progress['cfp']) }
+ %li.list-group-item{ class: class_for_todo(conference_progress['cfp']) }
+ %span{ class: icon_for_todo(conference_progress['cfp']) }
- if can? :update, Cfp.new(program_id: @program.id)
= link_to 'Set up call for papers', admin_conference_program_cfps_path(conference_progress['short_title'])
- else
Set up call for papers
- %li{'class'=>"list-group-item #{hidden_if_conference_over(conference)} #{class_for_todo(conference_progress['venue'])}"}
- %span{'class'=>icon_for_todo(conference_progress['venue'])}
+ %li.list-group-item{ class: class_for_todo(conference_progress['venue']) }
+ %span{ class: icon_for_todo(conference_progress['venue'])}
- if can? :update, Venue.new(conference: @conference)
- @conference.reload
- if conference.venue
@@ -32,32 +33,32 @@
- else
- @conference.reload
Add venue
- %li{ 'class' => "list-group-item #{hidden_if_conference_over(conference)} #{class_for_todo(conference_progress['rooms'])}" }
- %span{ 'class' => icon_for_todo(conference_progress['rooms']) }
+ %li.list-group-item{ class: class_for_todo(conference_progress['rooms']) }
+ %span{ class: icon_for_todo(conference_progress['rooms']) }
- if @conference.venue && (can? :update, @conference.venue.rooms.build)
= link_to 'Add rooms', admin_conference_venue_rooms_path(conference_progress['short_title'])
- else
Add rooms
- %li{ 'class' => "list-group-item #{hidden_if_conference_over(conference)} #{class_for_todo(conference_progress['tracks'])}" }
- %span{ 'class' => icon_for_todo(conference_progress['tracks']) }
+ %li.list-group-item{ class: class_for_todo(conference_progress['tracks']) }
+ %span{ class: icon_for_todo(conference_progress['tracks']) }
- if can? :update, @conference.program.tracks.build
= link_to 'Add tracks', admin_conference_program_tracks_path(conference_progress['short_title'])
- else
Add tracks
- %li{ 'class' => "list-group-item #{hidden_if_conference_over(conference)} #{class_for_todo(conference_progress['event_types'])}" }
- %span{ 'class' => icon_for_todo(conference_progress['event_types']) }
+ %li{ class: "list-group-item #{class_for_todo(conference_progress['event_types'])}" }
+ %span{ class: icon_for_todo(conference_progress['event_types']) }
- if can? :update, @conference.program.event_types.build
= link_to 'Add event types', admin_conference_program_event_types_path(conference_progress['short_title'])
- else
Add event types
- %li{ 'class' => "list-group-item #{hidden_if_conference_over(conference)} #{class_for_todo(conference_progress['difficulty_levels'])}" }
- %span{ 'class' => icon_for_todo(conference_progress['difficulty_levels']) }
+ %li{ class: "list-group-item #{class_for_todo(conference_progress['difficulty_levels'])}" }
+ %span{ class: icon_for_todo(conference_progress['difficulty_levels']) }
- if can? :update, @conference.program.difficulty_levels.build
= link_to 'Add difficulty levels', admin_conference_program_difficulty_levels_path(conference_progress['short_title'])
- else
Add difficulty levels
- %li{ class: "list-group-item #{hidden_if_conference_over(conference)} #{class_for_todo(conference_progress['splashpage'])}" }
- %span{ 'class' => icon_for_todo(conference_progress['splashpage']) }
+ %li.list-group-item{ class: "#{class_for_todo(conference_progress['splashpage'])}" }
+ %span{ class: icon_for_todo(conference_progress['splashpage']) }
- if can? :update, @conference
= link_to 'Set up a Splashpage', admin_conference_splashpage_path(conference_progress['short_title'])
- else
diff --git a/app/views/admin/conferences/edit.html.haml b/app/views/admin/conferences/edit.html.haml
index de0c5811..b675481b 100644
--- a/app/views/admin/conferences/edit.html.haml
+++ b/app/views/admin/conferences/edit.html.haml
@@ -9,24 +9,27 @@
= semantic_form_for(@conference, url: admin_conference_path(@conference.short_title), html: {multipart: true}) do |f|
= f.input :title, hint: "The full title of the conference, e.g. 'openSUSE Conference 2014'"
= f.input :short_title, hint: "A short title, e.g. 'oSC14', to be used in URLs"
- = f.input :description, hint: markdown_hint('A description of the conference.'), input_html: { rows: 5, data: { provide: 'markdown' } }
- = f.input :color, hint: 'The color will be used eg for the dashboard.', input_html: {size: 6, type: 'color'}
- = f.label 'Conference Logo'
+ = f.input :description,
+ hint: markdown_hint('A description of the conference. (Supports unsafe HTML.)'),
+ input_html: { rows: 5, data: { provide: 'markdown' } }
+ = f.input :color, hint: 'The will be used in emails.',
+ input_html: {size: 6, type: 'color'}
+ = f.label 'Conference Logo', for: 'conference_picture'
%br
- if @conference.picture?
= image_tag @conference.picture.thumb.url
- = f.input :picture, label: false, hint: 'This will be displayed on the front page.'
+ = f.input :picture, label: false, hint: 'This will be shown in the navigation bar and emails.'
= f.hidden_field :picture_cache
= f.input :custom_css,
- hint: "Add Custon CSS to the main page. You might find the class '.conference-#{@conference.short_title}' useful.",
- input_html: { rows: 5 }
+ hint: "Add custon CSS to all pages within the conference. The class .conference-#{@conference.short_title} is included on the body element.".html_safe,
+ input_html: { rows: 10, style: 'font-family: monospace' }
= f.input :ticket_layout, as: :select, collection: Conference.ticket_layouts.keys, hint: "Layout type for tickets of the conference."
= f.inputs name: 'Scheduling' do
= f.input :timezone, as: :time_zone, hint: 'The conference time zone'
- = f.input :start_date, as: :string, input_html: { id: 'conference-start-datepicker', readonly: 'readonly' }
- = f.input :end_date, as: :string, input_html: { id: 'conference-end-datepicker', readonly: 'readonly' }
+ = f.input :start_date, as: :string, input_html: { id: 'conference-start-datepicker' }
+ = f.input :end_date, as: :string, input_html: { id: 'conference-end-datepicker' }
= f.input :start_hour, input_html: {size: 2, type: 'number', min: 0, max: 23}, hint: rescheduling_hint(@affected_event_count)
= f.input :end_hour, input_html: {size: 2, type: 'number', min: 1, max: 24}, hint: rescheduling_hint(@affected_event_count)
= f.inputs name: 'Registrations' do
diff --git a/app/views/admin/conferences/show.html.haml b/app/views/admin/conferences/show.html.haml
index 76990b10..63a91d27 100644
--- a/app/views/admin/conferences/show.html.haml
+++ b/app/views/admin/conferences/show.html.haml
@@ -3,16 +3,16 @@
Dashboard for #{@conference.title}
%hr
.row
- .col-sm-3.col-xs-3
+ .col-sm-3.col-xs-6
= render "big_statistic",
icon: "user", subtitle: "Registration", value: @total_reg, delta: @new_reg
- .col-sm-3.col-xs-3
+ .col-sm-3.col-xs-6
= render "big_statistic",
icon: "check-square", subtitle: "Submission", value: @total_submissions, delta: @new_submissions
- .col-sm-3.col-xs-3
+ .col-sm-3.col-xs-6
= render "big_statistic",
icon: "file-text", subtitle: "Hour", value: @program_length, delta: @new_program_length
- .col-sm-3.col-xs-3
+ .col-sm-3.col-xs-6
= render "big_statistic",
icon: "archive", subtitle: "Withdrawn", value: @total_withdrawn, delta: @new_withdrawn
@@ -29,8 +29,20 @@
= render 'line_chart',
title: 'Submissions per week', data: @submissions
.col-md-4
- -# = render 'todo_list',
- -# conference_progress: @conference_progress, conference: @conference
+ - unless @conference.ended?
+ = render 'todo_list',
+ conference_progress: @conference_todo_list, conference: @conference
+ - else
+ .list-group
+ .list-group-item
+ %h4
+ Conference Progress
+ .progress
+ .progress-bar{ role: 'progressbar', 'aria-valuenow': 100,
+ 'aria-valuemin': 0, 'aria-valuemax': 100,
+ style: 'width: 100%;' }
+ Conference Complete!
+
.row#tickets
.col-md-8
= render 'line_chart',
@@ -43,14 +55,15 @@
%a{ href: '#distribution_all', 'data-toggle' => 'tab' }
%span.fa.fa-star
All
- %li
- %a{ href: '#distribution_confirmed', 'data-toggle' => 'tab' }
- %span.fa.fa-comment
- Confirmed
- %li
- %a{ href: '#distribution_withdrawn', 'data-toggle' => 'tab' }
- %span.fa.fa-archive
- Withdrawn
+ -# TODO-SNAP: Disabled for Snap!Con
+ %li
+ %a{ href: '#distribution_confirmed', 'data-toggle' => 'tab' }
+ %span.fa.fa-comment
+ Confirmed
+ %li
+ %a{ href: '#distribution_withdrawn', 'data-toggle' => 'tab' }
+ %span.fa.fa-archive
+ Withdrawn
.tab-content
.tab-pane.active#distribution_all
.row
@@ -58,33 +71,33 @@
= render 'donut_chart', title: 'Event types',
combined_data: @event_type_distribution
.col-md-4
- -# = render 'donut_chart', title: 'Difficulty levels',
- -# combined_data: @difficulty_levels_distribution
+ = render 'donut_chart', title: 'Difficulty levels',
+ combined_data: @difficulty_levels_distribution
.col-md-4
- -# = render 'donut_chart', title: 'Tracks',
- -# combined_data: @tracks_distribution
- .tab-pane#distribution_confirmed
- .row
- .col-md-4
- -# = render 'donut_chart', title: 'Event types',
- -# combined_data: @event_type_distribution_confirmed
- .col-md-4
- -# = render 'donut_chart', title: 'Difficulty levels',
- -# combined_data: @difficulty_levels_distribution_confirmed
- .col-md-4
- -# = render 'donut_chart', title: 'Tracks',
- -# combined_data: @tracks_distribution_confirmed
- .tab-pane#distribution_withdrawn
+ = render 'donut_chart', title: 'Tracks',
+ combined_data: @tracks_distribution
+ -# .tab-pane#distribution_withdrawn
.row
.col-md-4
= render 'donut_chart', title: 'Event types',
combined_data: @event_type_distribution_withdrawn
.col-md-4
= render 'donut_chart', title: 'Difficulty levels',
- combined_data: @difficulty_levels_distribution_withdrawn
+ combined_data: @difficulty_levels_distribution
.col-md-4
= render 'donut_chart', title: 'Tracks',
- combined_data: @tracks_distribution_withdrawn
+ combined_data: @tracks_distribution
+ -# .tab-pane#distribution_confirmed
+ .row
+ .col-md-4
+ = render 'donut_chart', title: 'Event types',
+ combined_data: @event_type_distribution_confirmed
+ .col-md-4
+ = render 'donut_chart', title: 'Difficulty levels',
+ combined_data: @difficulty_levels_distribution_confirmed
+ .col-md-4
+ = render 'donut_chart', title: 'Tracks',
+ combined_data: @tracks_distribution_confirmed
.row
.col-md-8
diff --git a/app/views/admin/event_types/_form.html.haml b/app/views/admin/event_types/_form.html.haml
index 91533877..526e9381 100644
--- a/app/views/admin/event_types/_form.html.haml
+++ b/app/views/admin/event_types/_form.html.haml
@@ -15,6 +15,7 @@
= f.input :description, as: :text, hint: markdown_hint, input_html: { rows: 5, data: { provide: 'markdown-editable' } }
= f.input :minimum_abstract_length, input_html: {size: 3}
= f.input :maximum_abstract_length, input_html: {size: 3}
+ = f.input :submission_instructions, as: :text, hint: markdown_hint, input_html: { rows: 5, data: { provide: 'markdown-editable' } }
= f.input :color, input_html: { size: 6, type: 'color' }
%p.text-right
= f.action :submit, as: :button, button_html: { class: 'btn btn-primary' }
diff --git a/app/views/admin/event_types/index.html.haml b/app/views/admin/event_types/index.html.haml
index e18cceeb..015a3397 100644
--- a/app/views/admin/event_types/index.html.haml
+++ b/app/views/admin/event_types/index.html.haml
@@ -10,6 +10,7 @@
%thead
%th Title
%th Description
+ %th Instructions
%th Length
%th Abstract Length
%th Color
@@ -21,6 +22,8 @@
= event_type.title
%td
= markdown(event_type.description)
+ %td
+ = markdown(event_type.submission_instructions)
%td
= event_type.length
Minutes
diff --git a/app/views/admin/survey_questions/_form.html.haml b/app/views/admin/survey_questions/_form.html.haml
index 2538c17c..eb861944 100644
--- a/app/views/admin/survey_questions/_form.html.haml
+++ b/app/views/admin/survey_questions/_form.html.haml
@@ -15,7 +15,7 @@
.row
.col-md-12
- = f.input :title
+ = f.input :title, input_html: { autofocus: true }
= f.input :mandatory
.survey-possible-answers{ class: @survey_question.choice? ? '' : 'hidden' }
= f.input :possible_answers, hint: 'Comma separated', input_html: { rows: 3 }
diff --git a/app/views/admin/surveys/_survey_stats.html.haml b/app/views/admin/surveys/_survey_stats.html.haml
index e551a7d1..cacf0b00 100644
--- a/app/views/admin/surveys/_survey_stats.html.haml
+++ b/app/views/admin/surveys/_survey_stats.html.haml
@@ -7,4 +7,4 @@
.panel-body
- question_replies = survey_question.survey_replies
- if question_replies.any?
- = pie_chart question_replies.group(:text).count, library: { legend: 'bottom', plotOptions: { pie: { dataLabels: { enabled: false }, showInLegend: true } } }
+ = pie_chart question_replies.group(:text).count, library: { legend: { position: 'bottom' }, plotOptions: { pie: { dataLabels: { enabled: false }, showInLegend: true } } }
diff --git a/app/views/admin/users/index.html.haml b/app/views/admin/users/index.html.haml
index 6e2c13df..3d52ce6c 100644
--- a/app/views/admin/users/index.html.haml
+++ b/app/views/admin/users/index.html.haml
@@ -20,6 +20,7 @@
%th{ width: '0' } Conferences Attended
%th{ width: '50%' } Roles
%th{ width: '0' } Actions
+ %th{ style: 'display: none' } Confirmed?
%tbody
:javascript
@@ -37,6 +38,7 @@
{
"data": "confirmed_at",
"render": function (data, type, row, meta) {
+ console.log(meta)
return 'Edit'+
'';
}
+ },
+ {
+ "data": "confirmed",
+ "className": 'hidden',
+ "render": false
}
]
});
diff --git a/app/views/admin/users/show.html.haml b/app/views/admin/users/show.html.haml
index b90e72d9..c0a8f1fb 100644
--- a/app/views/admin/users/show.html.haml
+++ b/app/views/admin/users/show.html.haml
@@ -12,8 +12,10 @@
.tab-content
#user-info-content.tab-pane{class: "#{'active' unless params[:tab] == 'submissions-content'}"}
- if can? :edit, @user
- .pull-right
+ .pull-right.btn-group
= link_to 'Edit', edit_admin_user_path(@user), class: 'btn btn-primary'
+ = link_to 'Delete', admin_user_path(@user),method: :delete, class: 'btn btn-danger',
+ data: {confirm: "Are you sure?"}
%table.table
- @show_attributes.each do |attr|
%tr
diff --git a/app/views/application/_big_statistic.haml b/app/views/application/_big_statistic.haml
index 7a77d29c..993903a7 100644
--- a/app/views/application/_big_statistic.haml
+++ b/app/views/application/_big_statistic.haml
@@ -1,13 +1,12 @@
- reverse ||= false
- variant = variant_from_delta(delta, reverse: reverse)
-.dashbox.text-center
- %span.fa
- = fa_icon(icon)
- = value
- %p.text-nowrap
- %small
+.dashbox.panel.panel-primary
+ .paenl-body.text-center
+ %span.fa
+ = fa_icon(icon)
+ = value
+ %p
= subtitle.pluralize(value)
- %span.label{ class: "label-#{variant}" }
- = delta
- since you last logged in
-
+ .label{ class: "label-#{variant}" }
+ = delta || 0
+ since last log in
diff --git a/app/views/conference_registrations/_event.html.haml b/app/views/conference_registrations/_event.html.haml
index 67a35ba2..dd389f66 100644
--- a/app/views/conference_registrations/_event.html.haml
+++ b/app/views/conference_registrations/_event.html.haml
@@ -1,33 +1,39 @@
-.panel.panel-default{class: ("panel-success" if event.registrations.include?(@registration)) }
+.panel.panel-default{ class: ('panel-success' if event.registrations.include?(registration)) }
.panel-heading
- %label{for: "registration_event_ids_#{event.id}"}
- %h3{style: 'margin: 0 auto;'}
- = hidden_field_tag "registration[event_ids][]", nil
- = check_box_tag "registration[event_ids][]", event.id, event.registrations.include?(@registration), id: "registration_event_ids_#{event.id}"
+ %label{ for: "registration_event_ids_#{event.id}" }
+ %h3{ style: 'margin: 0 auto;' }
+ = hidden_field_tag 'registration[event_ids][]', nil
+ = check_box_tag 'registration[event_ids][]', event.id, event.registrations.include?(registration), id: "registration_event_ids_#{event.id}"
= event.title
%small
= event.subtitle
+ .text-muted
+ = registered_text(event)
+ - if event.scheduled?
+ (Scheduled on: #{event.time.to_date})
+
.panel-body
- -# %p
- -# = canceled_replacement_event_label(event, event_schedule)
- -# = replacement_event_notice(event_schedule)
+ -#
+ %p
+ = canceled_replacement_event_label(event, event_schedule)
+ = replacement_event_notice(event_schedule)
%p
- if event.speakers.any?
presented by #{event.speaker_names}
- if event_schedule.present?
.h4.track
%span.fa.fa-clock-o
- %span.label{ style: "background-color: grey" }
+ %span.label{ style: 'background-color: grey' }
= event_schedule.start_time.strftime('%A, %B %-d %H:%M')
\-
= event_schedule.end_time.strftime('%H:%M')
%p
= markdown(truncate(event.abstract, length: 250))
-# TODO: More informative text or aria-label.
- = link_to 'more', conference_program_proposal_path(@conference.short_title, event.id), target: '_blank'
+ = link_to 'more', conference_program_proposal_path(conference.short_title, event.id), target: '_blank'
- if event.track
%span.track
%span.fa.fa-road
- %span.label{ style: "background-color: #{event.track.color}; color: #{ contrast_color(event.track.color) }" }
+ %span.label{ style: "background-color: #{event.track.color}; color: #{contrast_color(event.track.color)}" }
= event.track.name
diff --git a/app/views/conference_registrations/_registration_info.html.haml b/app/views/conference_registrations/_registration_info.html.haml
index e8968298..45d6f9fe 100644
--- a/app/views/conference_registrations/_registration_info.html.haml
+++ b/app/views/conference_registrations/_registration_info.html.haml
@@ -18,6 +18,6 @@
You are registered for #{pluralize(@registration.events.count, 'event')}.
They are at the end of this list.
- @registration.events_ordered.each do |event|
- = render 'conference_registrations/event', event: event, event_schedule: event.event_schedules.first
+ = render 'conference_registrations/event', event: event, event_schedule: event.event_schedules.first, conference: @conference, registration: @registration
= render 'conferences/code_of_conduct', organization: @conference.organization
diff --git a/app/views/conference_registrations/show.html.haml b/app/views/conference_registrations/show.html.haml
index 49cca609..77408022 100644
--- a/app/views/conference_registrations/show.html.haml
+++ b/app/views/conference_registrations/show.html.haml
@@ -9,9 +9,9 @@
-if @conference.venue
at
%strong
- = "#{@conference.venue.name},"
- = "#{@conference.venue.street},"
- = "#{@conference.venue.city} / #{@conference.venue.country_name}."
+ = "#{@conference.venue_name},"
+ = "#{@conference.venue_street},"
+ = "#{@conference.city} / #{@conference.country_name}."
%small
= date_string(@conference.start_date, @conference.end_date)
- unless @conference.code_of_conduct.blank?
diff --git a/app/views/conferences/_conference_details.html.haml b/app/views/conferences/_conference_details.html.haml
index d6512c78..b9fb7843 100644
--- a/app/views/conferences/_conference_details.html.haml
+++ b/app/views/conferences/_conference_details.html.haml
@@ -12,7 +12,7 @@
= date_string(conference.start_date, conference.end_date)
- if conference.venue
%p
- = "#{conference.venue.city}/#{conference.venue.country_name}"
+ = "#{conference.city}/#{conference.country_name}"
- unless conference.description.blank?
%p
= markdown(conference.description, escape_html=false)
diff --git a/app/views/conferences/_footer.haml b/app/views/conferences/_footer.haml
index 6b66478a..0ef3fa56 100644
--- a/app/views/conferences/_footer.haml
+++ b/app/views/conferences/_footer.haml
@@ -1,14 +1,15 @@
--# .scroll-top-wrapper
--# = link_to "#banner", class: "smoothscroll" do
--# %i.fa.fa-2x.fa-arrow-circle-up
+-#
+ scroll-top-wrapper
+ = link_to "#banner", class: "smoothscroll" do
+ %i.fa.fa-2x.fa-arrow-circle-up
--# :javascript
--# $(function(){
--# $(document).on( 'scroll', function(){
--# if ($(window).scrollTop() > 100) {
--# $('.scroll-top-wrapper').addClass('show');
--# } else {
--# $('.scroll-top-wrapper').removeClass('show');
--# }
--# });
--# });
+ :javascript
+ $(function(){
+ $(document).on( 'scroll', function(){
+ if ($(window).scrollTop() > 100) {
+ $('.scroll-top-wrapper').addClass('show');
+ } else {
+ $('.scroll-top-wrapper').removeClass('show');
+ }
+ });
+ });
diff --git a/app/views/conferences/_header.haml b/app/views/conferences/_header.haml
index fad8648c..f40fe600 100644
--- a/app/views/conferences/_header.haml
+++ b/app/views/conferences/_header.haml
@@ -2,13 +2,14 @@
#banner{ style: ("background-image: url(#{conference.picture_url})" if conference.picture_url) }
.container
.row
- .col-md-6.col-md-offset-3{id: (conference.picture? ? "header-image" : "header-no-image")}
+ .col-md-6.col-md-offset-3{ id: (conference.picture? ? "header-image" : "header-no-image") }
.row
- -# - if conference.picture?
- -# .col-md-4
- -# = image_tag(conference.picture_url,
- -# class: 'img-responsive img-center',
- -# id: 'splash-logo')
+ -#
+ - if conference.picture?
+ .col-md-4
+ = image_tag(conference.picture_url,
+ class: 'img-responsive img-center',
+ id: 'splash-logo')
.col-md-8
%h1
= conference.title.html_safe
diff --git a/app/views/conferences/_program.haml b/app/views/conferences/_program.haml
index 18d8a540..de07b475 100644
--- a/app/views/conferences/_program.haml
+++ b/app/views/conferences/_program.haml
@@ -2,7 +2,7 @@
%li
%a.smoothscroll{ href: '#program' } Program
%li
- = link_to('Schedule', events_conference_schedule_path(@conference))
+ = link_to('Schedule', events_conference_schedule_path(conference))
- cache [conference, highlights, tracks, booths, '#splash#program'] do
%section#program
diff --git a/app/views/conferences/_sponsors.haml b/app/views/conferences/_sponsors.haml
index 0bd5edb0..ab9e3638 100644
--- a/app/views/conferences/_sponsors.haml
+++ b/app/views/conferences/_sponsors.haml
@@ -27,7 +27,7 @@
.row
.col-md-12
%h3.text-center
- = "Interested in sponsoring #{conference.title}?"
+ Interested in sponsoring #{conference.title}?
= link_to(sponsorship_mailto(conference)) do
Please, contact us!
.trapezoid
diff --git a/app/views/conferences/_tickets.haml b/app/views/conferences/_tickets.haml
index b28f705e..940dc1ca 100644
--- a/app/views/conferences/_tickets.haml
+++ b/app/views/conferences/_tickets.haml
@@ -22,6 +22,6 @@
.word_break
= short_ticket_description(ticket)
%button.btn-block.btn.btn-lg.btn-success
- %i.fa.fa-ticket.fa-fw{"aria-hidden": true}
+ %i.fa.fa-ticket.fa-fw{ "aria-hidden": true }
= humanized_money_with_symbol(ticket.price)
.trapezoid
diff --git a/app/views/conferences/index.html.haml b/app/views/conferences/index.html.haml
index fbcb426e..fb45757c 100644
--- a/app/views/conferences/index.html.haml
+++ b/app/views/conferences/index.html.haml
@@ -18,8 +18,11 @@
#antiquated
- @antiquated.each do |conference|
= render '/conferences/conference_details', conference: conference
- - if @antiquated.empty? && @current.empty? && User.empty?
- = render partial: 'new_install'
+ %p
+ Add the events to your calendar:
+ %span.btn-group
+ = link_to("Days only", calendar_url(protocol: 'webcal', format: 'ics'), class: 'btn btn-default')
+ = link_to("Detailed", calendar_url(protocol: 'webcal', format: 'ics', full: true), class: 'btn btn-default')
-content_for :script_body do
:javascript
diff --git a/app/views/conferences/_new_install.html.haml b/app/views/conferences/new_install.html.haml
similarity index 92%
rename from app/views/conferences/_new_install.html.haml
rename to app/views/conferences/new_install.html.haml
index 1ec2bd02..d6cf8eef 100644
--- a/app/views/conferences/_new_install.html.haml
+++ b/app/views/conferences/new_install.html.haml
@@ -17,5 +17,5 @@
will the be administrator of it.
%p
We hope you enjoy using OSEM, if you have any question don't hesitate to
- = link_to('http://osem.io/#contact') do
+ = link_to('https://osem.io/#contact') do
contact us!
diff --git a/app/views/conferences/show.html.haml b/app/views/conferences/show.html.haml
index f498bf97..c34aa3c1 100644
--- a/app/views/conferences/show.html.haml
+++ b/app/views/conferences/show.html.haml
@@ -20,24 +20,22 @@
- if @unpaid_tickets
.row
.col-md-12
- .alert.alert-dismissable.alert-info.text-center#unpaid-tickets{role: 'alert'}
- %button.button.close{"data-dismiss" => "alert", "aria-label"=>"close"}
+ .alert.alert-dismissable.alert-info.text-center#unpaid-tickets{ role: 'alert' }
+ %button.button.close{ "data-dismiss" => "alert", "aria-label"=>"close" }
×
%p
You have unpaid tickets. Please complete your purchase.
= link_to('Purchase Tickets', new_conference_payment_path(@conference), class: 'btn btn-success btn-lg')
-
- if @user_needs_to_register
.row
- .col-md-12
- .alert.alert-dismissable.alert-warning.text-center#flash{role: 'alert'}
- %button.button.close{"data-dismiss" => "alert", 'aria-label': 'close'}
- ×
- %p
- You still need to complete your registration for #{@conference.title}.
- = link_to('Complete Registration', new_conference_conference_registration_path(@conference), class: 'btn btn-success btn-lg')
-
+ .col-md-12
+ .alert.alert-dismissable.alert-warning.text-center#flash{ role: 'alert' }
+ %button.button.close{ "data-dismiss" => "alert", 'aria-label': 'close' }
+ ×
+ %p
+ You still need to complete your registration for #{@conference.title}.
+ = link_to('Complete Registration', new_conference_conference_registration_path(@conference), class: 'btn btn-success btn-lg')
#splash
- if @conference.code_of_conduct.present?
@@ -79,29 +77,8 @@
sponsorship_levels: @sponsorship_levels,
sponsors: @sponsors
-
-# footer
- if @conference.splashpage.include_social_media
- if @conference.contact.has_social_media?
= render 'social_media', contact: @conference.contact
= render 'footer'
-
-
--# - content_for :script_head do
--# :javascript
--# var triangle_tcs = tinycolor("#{h(@conference.color)}").monochromatic();
--# var triangle_colors = triangle_tcs.map(function(t) {
--# return t.toHexString();
--# });
--# $(function () {
--# $(document).ready(function() {
--# var triangle_width = document.body.clientWidth;
--# var triangle_height = ($( "#banner" ).height() + 200 );
--# var pattern = Trianglify({ width: triangle_width,
--# height: triangle_height,
--# cell_size: 100,
--# x_colors: triangle_colors
--# });
--# $('#banner').css('background-image', 'url(' + 0 + ')');
--# });
--# });
diff --git a/app/views/devise/sessions/new.html.haml b/app/views/devise/sessions/new.html.haml
index 2c1bb613..dd40fb5c 100644
--- a/app/views/devise/sessions/new.html.haml
+++ b/app/views/devise/sessions/new.html.haml
@@ -11,7 +11,7 @@
= f.input :password
- if devise_mapping.rememberable?
%p.text-right.small
- = f.label 'Remember me'
+ = f.label 'Remember me', for: 'user_remember_me'
= f.check_box :remember_me
%p.text-right
= f.action :submit, as: :button, label: 'Sign In', button_html: {class: 'btn btn-success'}
diff --git a/app/views/layouts/_mailbot_footer.html.erb b/app/views/layouts/_mailbot_footer.html.erb
new file mode 100644
index 00000000..3cc8b3c3
--- /dev/null
+++ b/app/views/layouts/_mailbot_footer.html.erb
@@ -0,0 +1,12 @@
+
+