spina-conferences-primer_theme 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +33 -0
  4. data/Rakefile +36 -0
  5. data/app/assets/config/spina_conferences_primer_theme_manifest.js +8 -0
  6. data/app/assets/javascripts/spina/conferences/primer_theme/application.js +8 -0
  7. data/app/assets/javascripts/spina/conferences/primer_theme/controllers/slideshow_controller.es6 +68 -0
  8. data/app/assets/stylesheets/spina/conferences/primer_theme/_admin.sass +4 -0
  9. data/app/assets/stylesheets/spina/conferences/primer_theme/_custom.sass +0 -0
  10. data/app/assets/stylesheets/spina/conferences/primer_theme/_github.sass +2 -0
  11. data/app/assets/stylesheets/spina/conferences/primer_theme/_primer.sass +4 -0
  12. data/app/assets/stylesheets/spina/conferences/primer_theme/_turbolinks.sass +3 -0
  13. data/app/assets/stylesheets/spina/conferences/primer_theme/application.sass +13 -0
  14. data/app/controllers/spina/conferences/primer_theme/application_controller.rb +14 -0
  15. data/app/controllers/spina/conferences/primer_theme/conferences_controller.rb +55 -0
  16. data/app/controllers/spina/conferences/primer_theme/presentations_controller.rb +39 -0
  17. data/app/helpers/spina/conferences/primer_theme/application_helper.rb +64 -0
  18. data/app/helpers/spina/conferences/primer_theme/asset_helper.rb +48 -0
  19. data/app/helpers/spina/conferences/primer_theme/navigations_helper.rb +24 -0
  20. data/app/views/conferences_primer_theme/pages/about.html.haml +17 -0
  21. data/app/views/conferences_primer_theme/pages/committee.html.haml +9 -0
  22. data/app/views/conferences_primer_theme/pages/homepage.html.haml +6 -0
  23. data/app/views/conferences_primer_theme/pages/information.html.haml +6 -0
  24. data/app/views/conferences_primer_theme/pages/show.html.haml +2 -0
  25. data/app/views/layouts/conferences_primer_theme/application.html.haml +5 -0
  26. data/app/views/layouts/spina/conferences/primer_theme/application.html.haml +36 -0
  27. data/app/views/layouts/spina/conferences/primer_theme/conferences.html.haml +4 -0
  28. data/app/views/layouts/spina/conferences/primer_theme/presentations.html.haml +4 -0
  29. data/app/views/spina/application/_cookies.html.haml +14 -0
  30. data/app/views/spina/application/_current_conference_alert.html.haml +4 -0
  31. data/app/views/spina/application/_footer.html.haml +24 -0
  32. data/app/views/spina/application/_image_collection.html.haml +19 -0
  33. data/app/views/spina/application/_list_item.html.haml +1 -0
  34. data/app/views/spina/application/_logo.html.haml +1 -0
  35. data/app/views/spina/application/_mobile_navigation_item.html.haml +2 -0
  36. data/app/views/spina/application/_navigation.html.haml +12 -0
  37. data/app/views/spina/application/_navigation_item.html.haml +1 -0
  38. data/app/views/spina/application/_text.html.haml +1 -0
  39. data/app/views/spina/conferences/primer_theme/conferences/_conference.html.haml +16 -0
  40. data/app/views/spina/conferences/primer_theme/conferences/_conference.ics.erb +3 -0
  41. data/app/views/spina/conferences/primer_theme/conferences/_event.html.haml +12 -0
  42. data/app/views/spina/conferences/primer_theme/conferences/_event.ics.erb +3 -0
  43. data/app/views/spina/conferences/primer_theme/conferences/_events.html.haml +15 -0
  44. data/app/views/spina/conferences/primer_theme/conferences/_information.html.haml +4 -0
  45. data/app/views/spina/conferences/primer_theme/conferences/_institution.html.haml +6 -0
  46. data/app/views/spina/conferences/primer_theme/conferences/_institution_logo.html.haml +3 -0
  47. data/app/views/spina/conferences/primer_theme/conferences/_presentation.html.haml +14 -0
  48. data/app/views/spina/conferences/primer_theme/conferences/_presentation.ics.erb +3 -0
  49. data/app/views/spina/conferences/primer_theme/conferences/_presentation_type.html.haml +6 -0
  50. data/app/views/spina/conferences/primer_theme/conferences/_presentations.html.haml +29 -0
  51. data/app/views/spina/conferences/primer_theme/conferences/_sponsor.html.haml +9 -0
  52. data/app/views/spina/conferences/primer_theme/conferences/_sponsors.html.haml +6 -0
  53. data/app/views/spina/conferences/primer_theme/conferences/_tab.html.haml +1 -0
  54. data/app/views/spina/conferences/primer_theme/conferences/index.html.haml +21 -0
  55. data/app/views/spina/conferences/primer_theme/conferences/index.ics.erb +3 -0
  56. data/app/views/spina/conferences/primer_theme/conferences/show.html.haml +67 -0
  57. data/app/views/spina/conferences/primer_theme/conferences/show.ics.erb +5 -0
  58. data/app/views/spina/conferences/primer_theme/presentations/_abstract.html.haml +1 -0
  59. data/app/views/spina/conferences/primer_theme/presentations/_attachment.html.haml +6 -0
  60. data/app/views/spina/conferences/primer_theme/presentations/_attachments.html.haml +4 -0
  61. data/app/views/spina/conferences/primer_theme/presentations/show.html.haml +16 -0
  62. data/app/views/spina/pages/_committee_bio.html.haml +29 -0
  63. data/app/views/spina/pages/_committee_bios.html.haml +5 -0
  64. data/app/views/spina/pages/_constitution.html.haml +11 -0
  65. data/app/views/spina/pages/_contact.html.haml +4 -0
  66. data/app/views/spina/pages/_homepage_content.html.haml +15 -0
  67. data/app/views/spina/pages/_jumbotron.html.haml +2 -0
  68. data/app/views/spina/pages/_minutes.html.haml +8 -0
  69. data/app/views/spina/pages/_minutes_entry.html.haml +11 -0
  70. data/app/views/spina/pages/_partner_societies.html.haml +9 -0
  71. data/app/views/spina/pages/_partner_society.html.haml +25 -0
  72. data/config/initializers/assets.rb +13 -0
  73. data/config/initializers/themes/conferences_primer_theme.rb +247 -0
  74. data/config/locales/en.yml +149 -0
  75. data/config/routes.rb +11 -0
  76. data/lib/spina/conferences/primer_theme.rb +17 -0
  77. data/lib/spina/conferences/primer_theme/breadcrumbs/builder.rb +34 -0
  78. data/lib/spina/conferences/primer_theme/engine.rb +13 -0
  79. data/lib/spina/conferences/primer_theme/version.rb +9 -0
  80. data/lib/tasks/spina/conferences/primer_theme_tasks.rake +6 -0
  81. metadata +388 -0
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Spina
4
+ module Conferences
5
+ module PrimerTheme
6
+ # Helper for accessing navigation items
7
+ module NavigationsHelper
8
+ def main_navigation_items
9
+ @main_navigation_items ||= live_navigation_items('main')
10
+ end
11
+
12
+ def footer_navigation_items
13
+ @footer_navigation_items ||= live_navigation_items('footer')
14
+ end
15
+
16
+ private
17
+
18
+ def live_navigation_items(name)
19
+ ::Spina::NavigationItem.joins(:navigation).where(spina_navigations: { name: name }).roots.regular_pages.in_menu.live.sorted
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,17 @@
1
+ - cache current_page do
2
+ %h1= current_page.title
3
+
4
+ - cache partable_for(:text) do
5
+ - if has_content? :text
6
+ .mt-4= render partial: 'text', object: content(:text)
7
+ - cache partable_for(:contact) do
8
+ - if has_content? :contact
9
+ .mt-4= render partial: 'contact', object: content(:contact)
10
+ .clearfix.gutter
11
+ - cache partable_for(:constitution) do
12
+ .mt-4.col-12.col-md-6.float-md-left= render partial: 'constitution', object: content(:constitution)
13
+ - cache partable_for(:minutes) do
14
+ .mt-4.col-12.col-md-6.float-md-left= render partial: 'minutes', object: content(:minutes)
15
+ - cache partable_for(:partner_societies) do
16
+ - if has_content?(:partner_societies) && content(:partner_societies).structure_items.any?
17
+ .mt-4= render partial: 'partner_societies', object: content(:partner_societies)
@@ -0,0 +1,9 @@
1
+ - cache current_page do
2
+ %h1= current_page.title
3
+
4
+ - cache partable_for(:text) do
5
+ - if has_content? :text
6
+ .mt-4= render partial: 'text', object: content(:text)
7
+ - cache partable_for(:committee_bios) do
8
+ - if has_content?(:committee_bios) && content(:committee_bios).structure_items.any?
9
+ .mt-4= render partial: 'committee_bios', object: content(:committee_bios)
@@ -0,0 +1,6 @@
1
+ - content_for :hero do
2
+ - cache current_page do
3
+ - cache partable_for(:gallery) do
4
+ = render partial: 'homepage_content',
5
+ layout: has_content?(:gallery) && content(:gallery).images.any? ? 'image_collection' : 'jumbotron',
6
+ locals: { conference: latest_conference, advance: true, image_collection: content(:gallery) }
@@ -0,0 +1,6 @@
1
+ - cache current_page do
2
+ %h1= current_page.title
3
+
4
+ - cache partable_for(:text) do
5
+ - if has_content? :text
6
+ .mt-4= render partial: 'text', object: content(:text)
@@ -0,0 +1,2 @@
1
+ - cache current_page do
2
+ %h1= current_page.title
@@ -0,0 +1,5 @@
1
+ - content_for :breadcrumbs do
2
+ - if current_page.ancestors.any?
3
+ = ancestors
4
+
5
+ = render template: 'layouts/spina/conferences/primer_theme/application'
@@ -0,0 +1,36 @@
1
+ !!!
2
+ %html.height-full{ lang: I18n.locale }
3
+ %head
4
+ %meta{ charset: 'utf-8' }
5
+ %meta{ name: 'author', content: author }
6
+ %meta{ name: 'description', content: description }
7
+ %meta{ name: 'viewport', content: 'initial-scale=1.0' }
8
+ %meta{ name: 'og:title', content: title }
9
+ %meta{ name: 'og:description', content: description }
10
+ %meta{ name: 'turbolinks-cache-control', content: 'no-preview' }
11
+ %base{ target: '_blank' }
12
+ = csrf_meta_tags
13
+ %title= seo_title
14
+ = render 'spina/shared/google_site_verification'
15
+ = render 'spina/shared/analytics'
16
+ = stylesheet_link_tag 'spina/conferences/primer_theme/application', media: 'all', data: { turbolinks_track: true }
17
+ = javascript_include_tag 'spina/conferences/primer_theme/application', data: { turbolinks_track: true }
18
+ %script{ type: 'module', src: asset_path('@github/details-dialog-element/dist/index.js') }
19
+ %script{ type: 'module', src: asset_path('@github/include-fragment-element/dist/index.js') }
20
+ %script{ type: 'module', src: asset_path('@github/tab-container-element/dist/index.js') }
21
+ %script{ type: 'module', src: asset_path('@github/filter-input-element/dist/index.js') }
22
+ = yield :head
23
+ %body
24
+ .admin= render 'spina/shared/admin_bar'
25
+ %header= render 'navigation'
26
+ = render 'current_conference_alert'
27
+ %main
28
+ - if content_for? :flash
29
+ .flash-messages= yield :flash
30
+ = yield :hero
31
+ - if content_for? :breadcrumbs
32
+ .container-lg.p-responsive.mt-4= yield :breadcrumbs
33
+ = yield :header
34
+ .container-lg.p-responsive.mt-4= yield
35
+ %footer.container-lg.p-responsive.py-4= render 'footer'
36
+ = render 'spina/shared/social'
@@ -0,0 +1,4 @@
1
+ - content_for :breadcrumbs do
2
+ = breadcrumbs
3
+
4
+ = render template: 'layouts/spina/conferences/primer_theme/application'
@@ -0,0 +1,4 @@
1
+ - content_for :breadcrumbs do
2
+ = breadcrumbs
3
+
4
+ = render template: 'layouts/spina/conferences/primer_theme/application'
@@ -0,0 +1,14 @@
1
+ = render Primer::BorderBoxComponent.new(classes: 'Box--overlay') do |component|
2
+ = component.slot :header do
3
+ = button_tag(data: { 'close-dialog': true }, aria: { label: t(:'spina.close') }, type: 'button',
4
+ class: %w[Box-btn-octicon btn-octicon float-right]) do
5
+ = render Primer::OcticonComponent.new(icon: 'x')
6
+ .Box-title= t(:'.title')
7
+ = component.slot(:body) { t(:'.purpose') }
8
+ = component.slot :row do
9
+ = t :'.used.rails_html', cookie: tag.code(Rails.application.config.session_options[:key])
10
+ = component.slot :row do
11
+ - ga_cookie_names = %w[_ga _gat _gid].collect{ |cookie| tag.code(cookie) }.to_sentence.html_safe
12
+ - ga_cookie_info_url = 'https://developers.google.com/analytics/devguides/collection/analyticsjs/cookie-usage'
13
+ = t :'.used.google_analytics_html', cookies: link_to(ga_cookie_names, ga_cookie_info_url)
14
+ = t :'.no_advertising'
@@ -0,0 +1,4 @@
1
+ - content_for :flash do
2
+ - cache partable_for(:current_conference_alert, parent: current_account) do
3
+ - if current_account.has_content? :current_conference_alert
4
+ = render(Primer::FlashComponent.new(full: true, variant: :warning)) { current_account.content(:current_conference_alert) }
@@ -0,0 +1,24 @@
1
+ .d-flex.flex-column.flex-md-row-reverse.flex-md-items-baseline
2
+ .flex-auto.d-flex.flex-column.flex-sm-row.flex-items-baseline.mb-4.mb-md-0
3
+ %ul.list-style-none.flex-auto.mb-2.mb-sm-0.mr-sm-2
4
+ - footer_navigation_items.each do |item|
5
+ - cache item do
6
+ %li
7
+ = render Primer::ButtonComponent.new(tag: :a, href: item.materialized_path, variant: :small) { item.menu_title }
8
+ %details.details-reset.details-overlay.details-overlay-dark.mb-2.mb-sm-0.mr-sm-2
9
+ %summary.btn.btn-outline.btn-sm{ aria: { haspopup: 'dialog' } }
10
+ = octicon 'info'
11
+ = t :'.cookies'
12
+ %details-dialog
13
+ %include-fragment{ src: frontend_cookies_info_path }
14
+ .Box.Box--overlay.d-flex.flex-column
15
+ = button_tag(data: { 'close-dialog': true }, aria: { label: t(:'spina.close') }, type: 'button',
16
+ class: %w[Box-btn-octicon btn-octicon m-0 position-absolute right-0 top-0]) do
17
+ = render Primer::OcticonComponent.new(icon: 'x')
18
+ = render(Primer::SpinnerComponent.new(my: 6, mx: :auto))
19
+ - if current_account.has_content? :github_url
20
+ = render Primer::ButtonComponent.new(tag: :a, href: current_account.content(:github_url), button_type: :outline, variant: :small,
21
+ display: :inline_block) do
22
+ = render Primer::OcticonComponent.new(icon: 'mark-github')
23
+ = t :'.find_on_github'
24
+ %small.flex-auto.mr-sm-2.text-small.text-gray= t :'.copyright', name: Spina::Account.first.name, year: Date.today.year
@@ -0,0 +1,19 @@
1
+ - return if image_collection.images.none?
2
+
3
+ .position-relative{ data: { controller: :slideshow, slideshow: { incrementer: 0, advance: (true if local_assigns[:advance]) } } }
4
+ - image_collection.images.each_with_index do |image, index|
5
+ - if image.file.present?
6
+ = image_tag(main_app.url_for(image.file.variant(resize_to_fill: [1680, 600])), alt_description: image.file.name, draggable: false,
7
+ srcset: srcset(image.file, variant: { resize_to_fill: [1680, 600] }), hidden: index != 0,
8
+ data: { 'slideshow-target': 'slide' })
9
+ .position-absolute.top-0.left-0.right-0.bottom-0.container-lg.p-responsive{ class: ('position-absolute top-0' if local_assigns[:controls]) }
10
+ - if local_assigns[:controls]
11
+ .d-none.d-sm-flex.flex-justify-between.flex-items-center.height-full
12
+ = render Primer::ButtonComponent.new(data: { action: :'slideshow#previous' }) do
13
+ = render Primer::OcticonComponent.new(icon: 'arrow-left')
14
+ = t(:'.previous')
15
+ = render Primer::ButtonComponent.new(data: { action: :'slideshow#next' }) do
16
+ = t(:'.next')
17
+ = render Primer::OcticonComponent.new(icon: 'arrow-right')
18
+ - else
19
+ .text-white= yield
@@ -0,0 +1 @@
1
+ %li.list-style-none.py-4.border-bottom= yield
@@ -0,0 +1 @@
1
+ = render Primer::OcticonComponent.new(icon: 'home', mr: 2, height: 24)
@@ -0,0 +1,2 @@
1
+ = link_to mobile_navigation_item.menu_title, mobile_navigation_item.materialized_path,
2
+ class: %w[d-block py-2 border-top border-white-fade text-white]
@@ -0,0 +1,12 @@
1
+ .Header.bg-blue.px-3.px-md-4.px-lg-5
2
+ .Header-item.d-none.d-lg-flex.mt-n1.mb-n1= link_to render('logo'), root_path, class: 'Header-link'
3
+ .Header-item.Header-item--full.d-flex.d-lg-none{ aria: { hidden: true } }
4
+ = link_to render('logo'), root_path, class: %w[Header-link float-left]
5
+ %details.details-reset.text-right
6
+ %summary.btn-link.Header-link= octicon 'three-bars', height: 24
7
+ .d-flex.flex-column.flex-self-stretch.mt-3.text-left
8
+ = render partial: 'mobile_navigation_item', collection: main_navigation_items, cached: true
9
+ = link_to 'Conferences', frontend_conferences_url, class: %w[d-block py-2 border-top border-white-fade text-white]
10
+ = render partial: 'navigation_item', collection: main_navigation_items, cached: true
11
+ .Header-item.d-none.d-lg-flex
12
+ = link_to Spina::Admin::Conferences::Conference.model_name.human(count: 0), frontend_conferences_path, class: 'Header-link'
@@ -0,0 +1 @@
1
+ .Header-item.d-none.d-lg-flex= link_to navigation_item.menu_title, navigation_item.materialized_path, class: 'Header-link'
@@ -0,0 +1 @@
1
+ .markdown-body= text.html_safe
@@ -0,0 +1,16 @@
1
+ - cache [conference, conference.institutions, conference.institutions.collect(&:logo)] do
2
+ .d-flex.flex-column.flex-md-row-reverse.flex-justify-start.flex-md-justify-between
3
+ %ul.list-style-none.d-flex.flex-wrap.flex-md-justify-end.pl-md-2.pb-2.pb-md-0{ class: dom_class(conference.institutions) }
4
+ = render partial: 'institution', collection: conference.institutions, cached: -> institution { [institution, institution.logo] }
5
+ .flex-auto
6
+ %h3.mb-1
7
+ = link_to conference.name, frontend_conference_path(conference)
8
+ %ul.text-gray.list-style-none.d-flex.flex-column.flex-sm-row.flex-wrap
9
+ %li.mr-sm-3
10
+ = octicon 'calendar'
11
+ = t :'.dates_html', start_date: time_tag(conference.start_date, format: :date), finish_date: time_tag(conference.finish_date)
12
+ - if conference.institutions.any?
13
+ %li
14
+ = octicon 'location'
15
+ %address.d-inline= t :'.locations', institutions: conference.institutions.pluck(:name).to_sentence,
16
+ cities: conference.institutions.pluck(:city).uniq.to_sentence
@@ -0,0 +1,3 @@
1
+ <% cache conference do %>
2
+ <%= conference.to_event.to_ical -%>
3
+ <% end %>
@@ -0,0 +1,12 @@
1
+ - cache event do
2
+ .d-flex.flex-column.flex-sm-row
3
+ .flex-shrink-0.mr-sm-3.mb-3.mb-sm-0.col-sm-4
4
+ %span.f3-light.mb-1
5
+ = octicon 'clock', class: 'v-align-baseline'
6
+ = t :'.times_html', start_time: time_tag(event.start_time, format: :short), finish_time: time_tag(event.finish_time, format: :time)
7
+ .text-gray
8
+ = octicon 'location'
9
+ %address.d-inline= event.location
10
+ .flex-auto
11
+ %h3.mb-1= event.name
12
+ .text-gray= event.description.try(:html_safe)
@@ -0,0 +1,3 @@
1
+ <% cache event do %>
2
+ <%= event.to_event.to_ical -%>
3
+ <% end %>
@@ -0,0 +1,15 @@
1
+ - cache [events, @tab] do
2
+ - if events.any?
3
+ %filter-input.d-flex.flex-sm-justify-start{ aria: { owns: 'event_list' } }
4
+ .subnav.subnav-flush
5
+ .subnav-search.m-0.width-full
6
+ = search_field_tag 'search', nil, class: %w[form-control subnav-search-input width-full], aria: { label: t(:'.search') }
7
+ = octicon 'search', class: 'subnav-search-icon'
8
+ %div{ id: 'event_list' }
9
+ - if events.any?
10
+ %ul{ class: dom_class(events), data: { filter: { list: true } } }
11
+ = render partial: 'event', collection: events.sorted, layout: 'list_item', cached: true
12
+ - else
13
+ = render Primer::BlankslateComponent.new(title: t(:'.no_events'), icon: 'calendar')
14
+ = render Primer::BlankslateComponent.new(title: t(:'.no_matching_events'), icon: 'calendar', hidden: true,
15
+ data: { 'filter-empty-state': true })
@@ -0,0 +1,4 @@
1
+ - if text.present?
2
+ .markdown-body= text.try(:html_safe)
3
+ - else
4
+ = render Primer::BlankslateComponent.new(title: t(:'.no_information'), icon: 'info')
@@ -0,0 +1,6 @@
1
+ - cache [institution, institution.logo] do
2
+ %li
3
+ - if institution.logo.present?
4
+ = render partial: 'institution_logo', object: institution.logo, locals: { institution: institution }
5
+ - else
6
+ = institution.name
@@ -0,0 +1,3 @@
1
+ - if institution_logo.file.present?
2
+ = image_tag main_app.url_for(institution_logo.file.variant(resize_to_limit: [300, 60])), srcset: srcset(institution_logo.file,
3
+ variant: { resize_to_limit: [300, 60] }), alt_description: institution.name, draggable: false, class: 'p-1'
@@ -0,0 +1,14 @@
1
+ - cache [presentation, presentation.presenters] do
2
+ .d-flex.flex-column.flex-sm-row
3
+ .flex-shrink-0.mr-sm-3.mb-3.mb-sm-0.col-sm-3
4
+ %span.f3-light.mb-1
5
+ = octicon 'clock', class: 'v-align-baseline'
6
+ = time_tag presentation.start_datetime, format: :short
7
+ .text-gray
8
+ = octicon 'location'
9
+ %address.d-inline= presentation.session.room_name
10
+ .flex-auto
11
+ %h3.mb-1= link_to presentation.title, frontend_conference_presentation_path(conference, presentation)
12
+ .text-gray
13
+ = octicon presentation.presenters.many? ? 'people' : 'person'
14
+ %address.d-inline= presentation.presenters.collect(&:full_name_and_institution).to_sentence
@@ -0,0 +1,3 @@
1
+ <% cache presentation do %>
2
+ <%= presentation.to_event.to_ical -%>
3
+ <% end %>
@@ -0,0 +1,6 @@
1
+ - cache [presentation_type, @presentation_type] do
2
+ %li
3
+ = link_to frontend_conference_url(presentation_type.conference, presentation_type: presentation_type.id, tab: 'presentations'),
4
+ class: 'filter-item', aria: { current: @presentation_type == presentation_type ? 'page' : nil } do
5
+ = presentation_type.name.pluralize
6
+ %span.count{ title: t(:'.results') }= presentation_type.presentations.count
@@ -0,0 +1,29 @@
1
+ - cache [@conference.presentations, @presentation_type, @presentation_type.presentations,
2
+ @presentation_type.presentations.collect(&:presenters), @tab] do
3
+ .d-flex.flex-column.flex-lg-row
4
+ .col-12.col-lg-3.pr-lg-4.mb-4.mb-lg-0
5
+ %ul.filter-list
6
+ - cache [@conference.presentations, @presentation_type] do
7
+ %li
8
+ = link_to frontend_conference_url(@conference, tab: 'presentations'),
9
+ class: 'filter-item', aria: { current: @presentation_type == @conference ? 'page' : nil } do
10
+ = t('.all_presentation_types')
11
+ %span.count{ title: t(:'.results') }= @conference.presentations.count
12
+ = render partial: 'presentation_type', collection: @conference.presentation_types.sorted,
13
+ cached: -> presentation_type { [presentation_type, @presentation_type] }
14
+ .flex-auto.col-12.col-lg-8
15
+ - if @presentation_type.presentations.any?
16
+ %filter-input.d-flex.flex-sm-justify-start{ aria: { owns: 'presentation_list' } }
17
+ .subnav.subnav-flush
18
+ .subnav-search.m-0.width-full
19
+ = search_field_tag 'search', nil, class: %w[form-control subnav-search-input width-full], aria: { label: t(:'.search') }
20
+ = octicon 'search', class: 'subnav-search-icon'
21
+ %div{ id: 'presentation_list' }
22
+ - if @presentation_type.presentations.any?
23
+ %ul{ class: dom_class(@presentation_type.presentations), data: { filter: { list: true } } }
24
+ = render partial: 'presentation', collection: @presentation_type.presentations.sorted, layout: 'list_item',
25
+ locals: { conference: @conference }, cached: -> presentation { [presentation, presentation.presenters] }
26
+ - else
27
+ = render Primer::BlankslateComponent.new(title: t(:'.no_presentations'), icon: 'mortar-board')
28
+ = render Primer::BlankslateComponent.new(title: t(:'.no_matching_presentations'), icon: 'mortar-board', hidden: true,
29
+ data: { 'filter-empty-state': true })
@@ -0,0 +1,9 @@
1
+ - cache sponsor, sponsor.structure_parts.collect(&:structure_partable) do
2
+ %li.d-inline-block.m-2.v-align-middle
3
+ - if sponsor.has_content?(:logo) && sponsor.content(:logo).file.present?
4
+ = link_to sponsor.content(:website) do
5
+ = image_tag(main_app.url_for(sponsor.content(:logo).file.variant(resize_to_limit: [200, 60])),
6
+ srcset: srcset(sponsor.content(:logo).file, variant: { resize_to_limit: [200, 60] }),
7
+ alt_description: sponsor.content(:name), draggable: false)
8
+ - else
9
+ = link_to sponsor.content(:name), sponsor.content(:website)
@@ -0,0 +1,6 @@
1
+ .Subhead.Subhead--spacious
2
+ %h2.Subhead-heading= t :'.title'
3
+
4
+ %ul.ml-n2.mr-n2.mb-n2.mt-n2{ class: dom_class(sponsors), id: dom_id(sponsors) }
5
+ = render partial: 'sponsor', collection: sponsors.structure_items,
6
+ cached: -> sponsor { [sponsor, sponsor.structure_parts.collect(&:structure_partable)] }
@@ -0,0 +1 @@
1
+ .my-4{ role: 'tabpanel', hidden: hidden }= yield
@@ -0,0 +1,21 @@
1
+ .d-flex.flex-column-reverse.flex-sm-row
2
+ %filter-input.col-12.col-sm-8.mb-4.mb-sm-0.d-flex.flex-sm-justify-start{ aria: { owns: 'conference_list' } }
3
+ - if @conferences.any?
4
+ .subnav.subnav-flush
5
+ .subnav-search.m-0.width-full
6
+ = search_field_tag 'search', nil, class: %w[form-control subnav-search-input width-full], aria: { label: t(:'.search') }
7
+ = octicon 'search', class: 'subnav-search-icon'
8
+ .col-12.col-sm-4.mb-4.mb-sm-0.d-flex.flex-sm-justify-end
9
+ = render Primer::ButtonComponent.new(tag: :a, href: frontend_conferences_url(protocol: :webcal, format: :ics), button_type: :primary,
10
+ ml: [0, 6, nil, nil]) do
11
+ = render Primer::OcticonComponent.new(icon: 'calendar')
12
+ = t(:'.subscribe')
13
+ %div{ id: 'conference_list' }
14
+ - if @conferences.any?
15
+ %ul{ class: dom_class(@conferences), data: { filter: { list: true } } }
16
+ = render partial: 'conference', collection: @conferences, layout: 'list_item',
17
+ cached: -> conference { [conference, conference.institutions, conference.institutions.collect(&:logo)] }
18
+ - else
19
+ = render Primer::BlankslateComponent.new(title: t(:'.no_conferences'), icon: 'mortar-board')
20
+ = render Primer::BlankslateComponent.new(title: t(:'.no_matching_conferences'), icon: 'mortar-board', hidden: true,
21
+ data: { 'filter-empty-state': true })
@@ -0,0 +1,3 @@
1
+ <%= calendar name: current_account.name do -%>
2
+ <%= render partial: 'conference', collection: @conferences, cached: true -%>
3
+ <% end %>
@@ -0,0 +1,67 @@
1
+ - if @conference.has_content?(:submission_date) && @conference.content(:submission_date) >= Date.today
2
+ - content_for :flash do
3
+ - cache partable_for(:submission_url, :submission_date, :submission_text, parent: @conference) do
4
+ = render Primer::FlashComponent.new(variant: :warning, full: true) do
5
+ - cache partable_for(:submission_url, parent: @conference) do
6
+ - if @conference.content(:submission_url).present?
7
+ = link_to t(:'.submit_abstract'), @conference.content(:submission_url),
8
+ class: %i[btn btn-sm flash-action d-none d-sm-inline-block]
9
+ - cache partable_for(:submission_date, parent: @conference) do
10
+ %p
11
+ = octicon('clock')
12
+ = t :'.submit_by_html', date: time_tag(@conference.content(:submission_date), format: :short)
13
+ - cache partable_for(:submission_text, parent: @conference) do
14
+ - if @conference.content(:submission_text).present?
15
+ %p= @conference.content(:submission_text).html_safe
16
+
17
+ - content_for :header do
18
+ - cache [@conference, @conference.institutions, @conference.content(:gallery)&.images,
19
+ @conference.parts.collect(&:partable), @conference.content(:sponsors)&.structure_items,
20
+ @conference.content(:sponsors)&.structure_items&.extract_associated(structure_parts: [:structure_partable])] do
21
+ .container-lg.p-responsive.mb-4{ class: dom_class(@conference), id: dom_id(@conference) }
22
+ %h1.mb-1.mb-md-2= @conference.name
23
+ %ul.text-gray-dark.list-style-none.d-flex.flex-column.flex-sm-row.flex-wrap
24
+ %li.mr-sm-3.mb-1
25
+ = octicon 'calendar'
26
+ = t :'.dates_html', start_date: time_tag(@conference.start_date, format: :date), finish_date: time_tag(@conference.finish_date)
27
+ - if @conference.institutions.any?
28
+ - cache @conference.institutions do
29
+ %li.mb-1
30
+ = octicon 'location'
31
+ %address.d-inline= t :'.locations', institutions: @conference.institutions.pluck(:name).to_sentence,
32
+ cities: @conference.institutions.pluck(:city).uniq.to_sentence
33
+ - if @conference.institutions.any?
34
+ %ul.list-style-none.d-flex.flex-wrap.mt-4{ class: dom_class(@conference.institutions) }
35
+ = render partial: 'institution', collection: @conference.institutions,
36
+ cached: -> institution { [institution, institution.logo] }
37
+ - cache partable_for(:sponsors, parent: @conference) do
38
+ - if @conference.has_content?(:sponsors) && @conference.content(:sponsors).structure_items.any?
39
+ = render partial: 'sponsors', object: @conference.content(:sponsors)
40
+ - cache partable_for(:gallery, parent: @conference) do
41
+ - if @conference.has_content? :gallery
42
+ .mb-4= render partial: 'image_collection', object: @conference.content(:gallery), locals: { controls: true }
43
+
44
+ %tab-container
45
+ %nav.UnderlineNav
46
+ .container-lg.p-responsive.d-flex.flex-justify-between.flex-auto
47
+ .UnderlineNav-body{ role: 'tablist' }
48
+ = button_tag t(:'.tabs.information'), aria: { selected: (@tab == 'information').to_s }, class: 'UnderlineNav-item', role: 'tab',
49
+ type: 'button'
50
+ = button_tag t(:'.tabs.presentations'), aria: { selected: (@tab == 'presentations').to_s }, class: 'UnderlineNav-item',
51
+ role: 'tab', type: 'button'
52
+ = button_tag t(:'.tabs.events'), aria: { selected: (@tab == 'events').to_s }, class: 'UnderlineNav-item', role: 'tab',
53
+ type: 'button'
54
+ .UnderlineNav-actions
55
+ = render Primer::ButtonComponent.new(tag: :a, href: frontend_conference_url(@conference, protocol: :webcal, format: :ics),
56
+ button_type: :primary, variant: :small) do
57
+ = render Primer::OcticonComponent.new(icon: 'calendar')
58
+ = t(:'.subscribe')
59
+ .container-lg.p-responsive
60
+ - cache [partable_for(:text, parent: @conference), @tab] do
61
+ = render partial: 'information', layout: 'tab',
62
+ locals: { text: (@conference.content(:text) if @conference.has_content? :text), hidden: @tab != 'information' }
63
+ - cache [@conference.presentations, @presentation_type, @presentation_type.presentations,
64
+ @presentation_type.presentations.collect(&:presenters), @tab] do
65
+ = render partial: 'presentations', layout: 'tab', locals: { hidden: @tab != 'presentations' }
66
+ - cache [@conference.events, @tab] do
67
+ = render partial: 'events', layout: 'tab', locals: { events: @conference.events, hidden: @tab != 'events' }