spina-conferences-primer_theme-fork 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +33 -0
- data/Rakefile +36 -0
- data/app/assets/config/spina_conferences_primer_theme_manifest.js +9 -0
- data/app/assets/javascripts/spina/conferences/primer_theme/application.js +7 -0
- data/app/assets/javascripts/spina/conferences/primer_theme/controllers/slideshow_controller.es6 +68 -0
- data/app/assets/stylesheets/spina/conferences/primer_theme/_custom.sass +0 -0
- data/app/assets/stylesheets/spina/conferences/primer_theme/_custom_variables.sass +0 -0
- data/app/assets/stylesheets/spina/conferences/primer_theme/application.sass +44 -0
- data/app/controllers/spina/conferences/primer_theme/conferences/application_controller.rb +16 -0
- data/app/controllers/spina/conferences/primer_theme/conferences/conferences_controller.rb +72 -0
- data/app/controllers/spina/conferences/primer_theme/conferences/presentations_controller.rb +42 -0
- data/app/controllers/spina/conferences/primer_theme/journal/application_controller.rb +13 -0
- data/app/controllers/spina/conferences/primer_theme/journal/articles_controller.rb +69 -0
- data/app/controllers/spina/conferences/primer_theme/journal/issues_controller.rb +53 -0
- data/app/helpers/spina/conferences/primer_theme/application_helper.rb +36 -0
- data/app/helpers/spina/conferences/primer_theme/asset_helper.rb +51 -0
- data/app/helpers/spina/conferences/primer_theme/navigations_helper.rb +24 -0
- data/app/views/conferences_primer_theme/pages/about.html.haml +92 -0
- data/app/views/conferences_primer_theme/pages/committee.html.haml +42 -0
- data/app/views/conferences_primer_theme/pages/embedded_form.html.haml +9 -0
- data/app/views/conferences_primer_theme/pages/events.html.haml +59 -0
- data/app/views/conferences_primer_theme/pages/homepage.html.haml +34 -0
- data/app/views/conferences_primer_theme/pages/information.html.haml +5 -0
- data/app/views/conferences_primer_theme/pages/show.html.haml +2 -0
- data/app/views/layouts/conferences_primer_theme/application.html.haml +7 -0
- data/app/views/layouts/spina/conferences/primer_theme/application.html.haml +40 -0
- data/app/views/layouts/spina/conferences/primer_theme/conferences/conferences.html.haml +5 -0
- data/app/views/layouts/spina/conferences/primer_theme/conferences/presentations.html.haml +6 -0
- data/app/views/layouts/spina/conferences/primer_theme/journal/articles.html.haml +2 -0
- data/app/views/layouts/spina/conferences/primer_theme/journal/issues.html.haml +2 -0
- data/app/views/spina/admin/layout_partables/texts/_form.html.haml +4 -0
- data/app/views/spina/application/_cookies.html.haml +7 -0
- data/app/views/spina/application/_current_conference_alert.html.haml +4 -0
- data/app/views/spina/application/_footer.html.haml +17 -0
- data/app/views/spina/application/_footer_content.html.haml +13 -0
- data/app/views/spina/application/_list_item.html.haml +1 -0
- data/app/views/spina/application/_logo.html.haml +1 -0
- data/app/views/spina/application/_mobile_navigation_item.html.haml +12 -0
- data/app/views/spina/application/_mobile_navigation_items.html.haml +4 -0
- data/app/views/spina/application/_navigation.html.haml +11 -0
- data/app/views/spina/application/_navigation_item.html.haml +11 -0
- data/app/views/spina/application/_text.html.haml +1 -0
- data/app/views/spina/conferences/primer_theme/conferences/conferences/_conference.html.haml +15 -0
- data/app/views/spina/conferences/primer_theme/conferences/conferences/_event.html.haml +12 -0
- data/app/views/spina/conferences/primer_theme/conferences/conferences/_events.html.haml +16 -0
- data/app/views/spina/conferences/primer_theme/conferences/conferences/_header.html.haml +47 -0
- data/app/views/spina/conferences/primer_theme/conferences/conferences/_institution.html.haml +5 -0
- data/app/views/spina/conferences/primer_theme/conferences/conferences/_institution_logo.html.haml +4 -0
- data/app/views/spina/conferences/primer_theme/conferences/conferences/_presentation.html.haml +15 -0
- data/app/views/spina/conferences/primer_theme/conferences/conferences/_presentation_type.html.haml +5 -0
- data/app/views/spina/conferences/primer_theme/conferences/conferences/_presentations.html.haml +29 -0
- data/app/views/spina/conferences/primer_theme/conferences/conferences/_submission_flash.html.haml +10 -0
- data/app/views/spina/conferences/primer_theme/conferences/conferences/index.html.haml +23 -0
- data/app/views/spina/conferences/primer_theme/conferences/conferences/show.html.haml +37 -0
- data/app/views/spina/conferences/primer_theme/conferences/kaminari/_gap.html.haml +2 -0
- data/app/views/spina/conferences/primer_theme/conferences/kaminari/_next_page.html.haml +9 -0
- data/app/views/spina/conferences/primer_theme/conferences/kaminari/_page.html.haml +10 -0
- data/app/views/spina/conferences/primer_theme/conferences/kaminari/_paginator.html.haml +17 -0
- data/app/views/spina/conferences/primer_theme/conferences/kaminari/_prev_page.html.haml +9 -0
- data/app/views/spina/conferences/primer_theme/conferences/presentations/_abstract.html.haml +2 -0
- data/app/views/spina/conferences/primer_theme/conferences/presentations/_attachment.html.haml +5 -0
- data/app/views/spina/conferences/primer_theme/conferences/presentations/_attachments.html.haml +5 -0
- data/app/views/spina/conferences/primer_theme/conferences/presentations/show.html.haml +18 -0
- data/app/views/spina/conferences/primer_theme/journal/articles/_authorship.html.haml +6 -0
- data/app/views/spina/conferences/primer_theme/journal/articles/_metadata.html.haml +36 -0
- data/app/views/spina/conferences/primer_theme/journal/articles/show.html.haml +70 -0
- data/app/views/spina/conferences/primer_theme/journal/issues/_article.html.haml +15 -0
- data/app/views/spina/conferences/primer_theme/journal/issues/_issue.html.haml +17 -0
- data/app/views/spina/conferences/primer_theme/journal/issues/_issue_cover.html.haml +6 -0
- data/app/views/spina/conferences/primer_theme/journal/issues/index.html.haml +30 -0
- data/app/views/spina/conferences/primer_theme/journal/issues/show.html.haml +27 -0
- data/config/initializers/assets.rb +13 -0
- data/config/initializers/mime_types.rb +1 -0
- data/config/initializers/primer.rb +3 -0
- data/config/initializers/themes/conferences_primer_theme.rb +237 -0
- data/config/locales/en.rb +16 -0
- data/config/locales/en.yml +198 -0
- data/config/routes.rb +17 -0
- data/db/migrate/20210206170704_change_current_conference_alert_to_text.rb +46 -0
- data/lib/spina/conferences/primer_theme.rb +17 -0
- data/lib/spina/conferences/primer_theme/breadcrumbs/builder.rb +34 -0
- data/lib/spina/conferences/primer_theme/engine.rb +13 -0
- data/lib/spina/conferences/primer_theme/version.rb +9 -0
- data/lib/tasks/spina/conferences/primer_theme_tasks.rake +6 -0
- metadata +396 -0
@@ -0,0 +1,53 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Spina
|
4
|
+
module Conferences
|
5
|
+
module PrimerTheme
|
6
|
+
module Journal
|
7
|
+
# User-facing controller for journal issues
|
8
|
+
class IssuesController < ApplicationController
|
9
|
+
before_action :set_journal
|
10
|
+
before_action :set_issue, :set_breadcrumb, only: :show
|
11
|
+
before_action :set_metadata
|
12
|
+
|
13
|
+
def index
|
14
|
+
# having multiple journals is not currently allowed anyway
|
15
|
+
@issues = if current_spina_user.present?
|
16
|
+
Admin::Journal::Issue.sorted_desc
|
17
|
+
else
|
18
|
+
Admin::Journal::Issue.sorted_desc.where('date <= ?', Time.zone.today)
|
19
|
+
end
|
20
|
+
@latest_issue = @issues.first
|
21
|
+
end
|
22
|
+
|
23
|
+
def show
|
24
|
+
@articles = current_spina_user.present? ? @issue.articles : @issue.articles.visible
|
25
|
+
add_breadcrumb t('spina.conferences.primer_theme.journal.volume_issue', volume_number: @issue.volume.number, issue_number: @issue.number)
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def set_journal
|
31
|
+
@journal = Admin::Journal::Journal.instance
|
32
|
+
end
|
33
|
+
|
34
|
+
def set_issue
|
35
|
+
@issue = Admin::Journal::Issue.includes(:volume, :articles).find(params[:id])
|
36
|
+
rescue ActiveRecord::RecordNotFound
|
37
|
+
send_file Rails.root.join('public/404.html'), type: 'text/html; charset=utf-8', status: 404
|
38
|
+
end
|
39
|
+
|
40
|
+
def set_breadcrumb
|
41
|
+
add_breadcrumb @journal.name, frontend_issues_path
|
42
|
+
add_breadcrumb Admin::Journal::Issue.model_name.human.pluralize, frontend_issues_path
|
43
|
+
end
|
44
|
+
|
45
|
+
def set_metadata
|
46
|
+
@title = @journal.name
|
47
|
+
@description = ActionView::Base.full_sanitizer.sanitize(@journal.content(:description))
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Spina
|
4
|
+
module Conferences
|
5
|
+
module PrimerTheme
|
6
|
+
# Base helper
|
7
|
+
module ApplicationHelper
|
8
|
+
include Spina::PagesHelper
|
9
|
+
|
10
|
+
# Because the upper bound is exclusive a conference is current the day after it ends
|
11
|
+
def current_conference
|
12
|
+
Spina::Admin::Conferences::Conference.order(dates: :asc).find_by('upper(dates) >= ?', Date.today)
|
13
|
+
end
|
14
|
+
|
15
|
+
def ancestors
|
16
|
+
return [] if current_page.blank?
|
17
|
+
|
18
|
+
render Primer::BreadcrumbComponent.new(mb: 4) do |component|
|
19
|
+
current_page.ancestors.each do |ancestor|
|
20
|
+
component.item(href: ancestor.materialized_path) { ancestor.menu_title }
|
21
|
+
end
|
22
|
+
component.item(selected: true) { current_page.menu_title }
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def calendar(name:)
|
27
|
+
Icalendar::Calendar.new
|
28
|
+
.tap { |calendar| calendar.x_wr_calname = name }
|
29
|
+
.tap { |calendar| yield(calendar) }
|
30
|
+
.tap(&:publish)
|
31
|
+
.then(&:to_ical)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Spina
|
4
|
+
module Conferences
|
5
|
+
module PrimerTheme
|
6
|
+
# Helper for computing asset sources
|
7
|
+
module AssetHelper
|
8
|
+
def srcset(image, **options)
|
9
|
+
return if image.blank?
|
10
|
+
|
11
|
+
options = options.symbolize_keys
|
12
|
+
variant_options = options.delete(:variant)
|
13
|
+
return if variant_options.blank?
|
14
|
+
|
15
|
+
factors = options.delete(:factors) || DEFAULT_FACTORS
|
16
|
+
variants_for image, variant_options: variant_options, factors: factors
|
17
|
+
end
|
18
|
+
|
19
|
+
def srcset_string(image, **options)
|
20
|
+
srcset(image, **options).collect { |key, value| "#{key} #{value}" }
|
21
|
+
.join(', ')
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
METHODS_TO_RESIZE = %i[resize_to_limit resize_to_fit resize_to_fill resize_and_pad].freeze
|
27
|
+
DEFAULT_FACTORS = [1, 2, 3, 4].freeze
|
28
|
+
|
29
|
+
def variants_for(image, variant_options:, factors:)
|
30
|
+
factors.inject({}) { |srcset, factor| srcset.update(variant_url(image, variant_options, factor) => "#{factor}x") }
|
31
|
+
end
|
32
|
+
|
33
|
+
def variant_url(image, variant_options, factor)
|
34
|
+
main_app.url_for(image.variant(resize_options(variant_options, factor)))
|
35
|
+
end
|
36
|
+
|
37
|
+
def resize_options(variant_options, factor)
|
38
|
+
variant_options.to_h { |key, value| [key, resize_dimensions_for_key(key, factor, value)] }
|
39
|
+
end
|
40
|
+
|
41
|
+
def resize_dimensions_for_key(key, factor, dimensions)
|
42
|
+
METHODS_TO_RESIZE.include?(key) ? dimensions.collect { |dimension| resize_dimension(dimension, factor) } : dimensions
|
43
|
+
end
|
44
|
+
|
45
|
+
def resize_dimension(dimension = 0, factor = 0)
|
46
|
+
factor * dimension
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -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,92 @@
|
|
1
|
+
- cache current_page do
|
2
|
+
= render(Primer::HeadingComponent.new) { current_page.title }
|
3
|
+
|
4
|
+
- if content(:text).present?
|
5
|
+
= render(Primer::MarkdownComponent.new(mt: 4)) { content.html(:text) }
|
6
|
+
- if content(:contact).present?
|
7
|
+
= render Primer::SubheadComponent.new(mt: 4) do |component|
|
8
|
+
= component.heading { t :'.contact.title' }
|
9
|
+
= render(Primer::MarkdownComponent.new) { content.html(:contact) }
|
10
|
+
|
11
|
+
.clearfix.gutter
|
12
|
+
= render Primer::BoxComponent.new(mt: 4, col: [12, nil, 6, nil], float: [nil, nil, :left, nil]) do
|
13
|
+
= render Primer::SubheadComponent.new do |component|
|
14
|
+
= component.heading { t :'.constitution.title' }
|
15
|
+
- if content(:constitution).present?
|
16
|
+
= render Primer::FlexComponent.new(align_items: :center, py: 1) do
|
17
|
+
= render Primer::FlexItemComponent.new(flex_auto: true, pr: 1) do
|
18
|
+
= t :'.constitution.uploaded',
|
19
|
+
date: l(Spina::Attachment.find(content(:constitution).attachment_id).created_at.to_date, format: :long)
|
20
|
+
= render Primer::ButtonComponent.new(tag: :a, href: content.attachment_url(:constitution), ml: 2, download: '') do
|
21
|
+
= render Primer::OcticonComponent.new('desktop-download')
|
22
|
+
= t :'.constitution.download'
|
23
|
+
- else
|
24
|
+
= render Primer::BlankslateComponent.new(title: t(:'.constitution.no_constitution'), icon: 'law')
|
25
|
+
|
26
|
+
= render Primer::BoxComponent.new(mt: 4, col: [12, nil, 6, nil], float: [nil, nil, :left, nil]) do
|
27
|
+
= render Primer::SubheadComponent.new do |component|
|
28
|
+
= component.heading { t :'.minutes.title' }
|
29
|
+
- if content(:minutes).present?
|
30
|
+
%ul
|
31
|
+
- repeater :minutes do |minutes_entry|
|
32
|
+
%li.list-style-none.py-1.d-flex.flex-items-center
|
33
|
+
= render Primer::FlexItemComponent.new(flex_auto: true) do
|
34
|
+
- if minutes_entry.content(:date).present?
|
35
|
+
= t(:'.minutes.minutes_for_html', date: time_tag(minutes_entry.content(:date)))
|
36
|
+
- else
|
37
|
+
= t(:'.minutes.no_date')
|
38
|
+
- if minutes_entry.content(:attachment).present?
|
39
|
+
= render Primer::ButtonComponent.new(tag: :a, ml: 2, href: minutes_entry.content.attachment_url(:attachment),
|
40
|
+
download: '') do
|
41
|
+
= render Primer::OcticonComponent.new('desktop-download')
|
42
|
+
= t(:'.minutes.download')
|
43
|
+
- else
|
44
|
+
= render(Primer::TextComponent.new(color: :text_secondary, font_size: 6)) { t :'.minutes.no_file' }
|
45
|
+
- else
|
46
|
+
= render Primer::BlankslateComponent.new(title: t(:'.minutes.no_minutes'), icon: 'file')
|
47
|
+
|
48
|
+
= render Primer::BoxComponent.new(mt: 4, col: [12, nil, 6, nil], float: [nil, nil, :left, nil]) do
|
49
|
+
- if content(:documents).present?
|
50
|
+
= render Primer::SubheadComponent.new do |component|
|
51
|
+
= component.heading { t :'.documents.title' }
|
52
|
+
%ul
|
53
|
+
- repeater :documents do |document|
|
54
|
+
%li.list-style-none.py-1.d-flex.flex-items-center
|
55
|
+
= render(Primer::TextComponent.new(tag: :div, flex: :auto)) { document.content(:name).presence || t(:'.documents.no_name') }
|
56
|
+
- if document.content(:attachment).present?
|
57
|
+
= render Primer::ButtonComponent.new(tag: :a, ml: 2, href: document.content.attachment_url(:attachment), download: '') do
|
58
|
+
= render Primer::OcticonComponent.new('desktop-download')
|
59
|
+
= t :'.documents.download'
|
60
|
+
- else
|
61
|
+
= render(Primer::TextComponent.new(tag: :div, font_size: 6, color: :text_secondary)) { t :'.documents.no_file' }
|
62
|
+
|
63
|
+
= render Primer::SubheadComponent.new(mt: 4) do |component|
|
64
|
+
= component.heading { t :'.partner_societies.title' }
|
65
|
+
- if content(:partner_societies).present?
|
66
|
+
%ul
|
67
|
+
- repeater :partner_societies do |partner_society|
|
68
|
+
%li.list-style-none.py-4.border-bottom
|
69
|
+
= render Primer::FlexComponent.new(direction: [:column, nil, :row_reverse, nil], align_items: :start) do
|
70
|
+
= render Primer::BaseComponent.new(tag: :div, flex: :auto) do
|
71
|
+
= render Primer::HeadingComponent.new(tag: :h3, mb: 1) do
|
72
|
+
= render Primer::FlexComponent.new(flex_wrap: true, justify_content: :space_between) do
|
73
|
+
- if partner_society.content(:name).present?
|
74
|
+
= render(Primer::TextComponent.new(tag: :div)) { partner_society.content(:name) }
|
75
|
+
= render Primer::ButtonGroupComponent.new(aria: { label: t(:'.partner_societies.contact_buttons') }) do |component|
|
76
|
+
- if partner_society.content(:website).present?
|
77
|
+
= component.button(tag: :a, href: partner_society.content(:website)) do
|
78
|
+
= render Primer::OcticonComponent.new('browser')
|
79
|
+
= t(:'.partner_societies.website')
|
80
|
+
- if partner_society.content(:email_address).present?
|
81
|
+
= component.button(tag: :a, href: "mailto:#{partner_society.content(:email_address)}") do
|
82
|
+
= render Primer::OcticonComponent.new('mail')
|
83
|
+
= t(:'.partner_societies.email')
|
84
|
+
- if partner_society.content(:description).present?
|
85
|
+
= render Primer::MarkdownComponent.new(color: :text_secondary) do
|
86
|
+
= partner_society.content(:description).try(:html_safe)
|
87
|
+
- if partner_society.content(:logo).present?
|
88
|
+
= partner_society.content.image_tag(:logo, { resize_to_limit: [200, 150] }, size: nil, draggable: false,
|
89
|
+
srcset: srcset(partner_society.content(:logo), variant: { resize_to_limit: [200, 150] }),
|
90
|
+
class: %w[mt-4 mt-md-0 mr-md-4])
|
91
|
+
- else
|
92
|
+
= render Primer::BlankslateComponent.new(title: t(:'.partner_societies.no_societies'), icon: 'organization')
|
@@ -0,0 +1,42 @@
|
|
1
|
+
- cache current_page do
|
2
|
+
= render(Primer::HeadingComponent.new) { current_page.title }
|
3
|
+
|
4
|
+
- if content(:text).present?
|
5
|
+
= render(Primer::MarkdownComponent.new(mt: 4)) { content.html(:text) }
|
6
|
+
|
7
|
+
- if content(:committee_bios).present?
|
8
|
+
%ul.mt-4
|
9
|
+
- repeater(:committee_bios) do |committee_bio|
|
10
|
+
%li.list-style-none.py-4.border-bottom
|
11
|
+
= render Primer::FlexComponent.new(direction: [:column, nil, :row, nil], align_items: :start) do
|
12
|
+
- if committee_bio.content(:profile_picture).present?
|
13
|
+
= render Primer::AvatarComponent.new(src: committee_bio.content.image_url(:profile_picture, resize_to_fill: [150, 150]),
|
14
|
+
srcset: srcset_string(committee_bio.content(:profile_picture),
|
15
|
+
variant: { resize_to_fill: [150, 150] }),
|
16
|
+
draggable: false, alt: committee_bio.content(:profile_picture).alt, size: 150,
|
17
|
+
mr: [nil, nil, 3, nil], mb: [3, nil, 0, nil], flex_shrink: 0)
|
18
|
+
= render Primer::FlexItemComponent.new(flex_auto: true) do
|
19
|
+
= render Primer::FlexComponent.new(direction: [:column, nil, :row, nil], mb: 1) do
|
20
|
+
= render Primer::BoxComponent.new do
|
21
|
+
- if committee_bio.content(:name).present?
|
22
|
+
= render(Primer::HeadingComponent.new(tag: :h3)) do
|
23
|
+
- if committee_bio.content(:role).present?
|
24
|
+
= t :'.name_and_role', name: committee_bio.content(:name), role: committee_bio.content(:role)
|
25
|
+
- else
|
26
|
+
= committee_bio.content(:name)
|
27
|
+
- if committee_bio.content(:institution).present?
|
28
|
+
= render(Primer::HeadingComponent.new(tag: :h4)) { committee_bio.content(:institution) }
|
29
|
+
= render Primer::ButtonGroupComponent.new(mt: [1, nil, 0, nil], ml: [nil, nil, 1, nil],
|
30
|
+
aria: { label: t(:'.contact_buttons') }) do |component|
|
31
|
+
- if committee_bio.content(:twitter_profile).present?
|
32
|
+
= component.button(tag: :a, href: committee_bio.content(:twitter_profile)) do
|
33
|
+
= render Primer::OcticonComponent.new('link-external')
|
34
|
+
= t(:'.twitter')
|
35
|
+
- if committee_bio.content(:facebook_profile).present?
|
36
|
+
= component.button(tag: :a, href: committee_bio.content(:facebook_profile)) do
|
37
|
+
= render Primer::OcticonComponent.new('link-external')
|
38
|
+
= t(:'.facebook')
|
39
|
+
- if committee_bio.content(:bio).present?
|
40
|
+
= render(Primer::TextComponent.new(tag: :div, color: :text_secondary)) { committee_bio.content.html(:bio) }
|
41
|
+
- else
|
42
|
+
= render Primer::BlankslateComponent.new(title: t(:'.no_bios'), icon: 'file')
|
@@ -0,0 +1,9 @@
|
|
1
|
+
- cache current_page do
|
2
|
+
= render(Primer::HeadingComponent.new) { current_page.title }
|
3
|
+
|
4
|
+
- if content(:text).present?
|
5
|
+
= render(Primer::MarkdownComponent.new(mt: 4)) { content.html(:text) }
|
6
|
+
|
7
|
+
- if content(:embed_url).present?
|
8
|
+
= render Primer::BoxComponent.new(mt: 4, col: 12) do
|
9
|
+
%iframe#form_frame{ src: content(:embed_url), allowfullscreen: true }
|
@@ -0,0 +1,59 @@
|
|
1
|
+
- cache current_page do
|
2
|
+
= render(Primer::HeadingComponent.new) { current_page.title }
|
3
|
+
|
4
|
+
- if content(:text).present?
|
5
|
+
= render(Primer::MarkdownComponent.new(mt: 4)) { content.html(:text) }
|
6
|
+
|
7
|
+
- if content(:events_list).present?
|
8
|
+
= render Primer::SubheadComponent.new(mt: 4) do |component|
|
9
|
+
= component.heading { t :'.upcoming' }
|
10
|
+
- content(:events_list).filter { |event| event.content(:start_time).blank? || event.content(:start_time) >= Time.now }.then do |events|
|
11
|
+
- if events.any?
|
12
|
+
%ul
|
13
|
+
- repeater(events) do |event|
|
14
|
+
%li.list-style-none.py-4.border-bottom
|
15
|
+
= render Primer::FlexComponent.new(direction: :column, align_items: :start) do
|
16
|
+
- if event.content(:name).present?
|
17
|
+
= render(Primer::HeadingComponent.new(tag: :h3, flex: :auto)) { event.content(:name) }
|
18
|
+
= render Primer::HeadingComponent.new(tag: :h4, flex: :auto) do
|
19
|
+
- if event.content(:start_time).present?
|
20
|
+
= t(:'.time_and_place_html',
|
21
|
+
time: time_tag(event.content(:start_time), format: :ordinal_datetime_with_year),
|
22
|
+
place: event.content(:location).presence || t('.location_tbc'))
|
23
|
+
- else
|
24
|
+
= t(:'.time_and_place_html', time: t('.time_tbc'), place: event.content(:location).presence || t('.location_tbc'))
|
25
|
+
- if event.content(:description).present?
|
26
|
+
= render(Primer::TextComponent.new(mt: 1, color: :text_secondary)) { event.content.html(:description) }
|
27
|
+
- if event.content(:url).present?
|
28
|
+
= render Primer::ButtonComponent.new(tag: :a, href: event.content(:url), mt: 2) do
|
29
|
+
= render Primer::OcticonComponent.new('link-external')
|
30
|
+
= t :'.more_info'
|
31
|
+
- else
|
32
|
+
= render Primer::BlankslateComponent.new(title: t(:'.no_events'), icon: 'calendar')
|
33
|
+
= render Primer::SubheadComponent.new(mt: 4) do |component|
|
34
|
+
= component.heading { t :'.past' }
|
35
|
+
- content(:events_list).filter { |event| event.content(:start_time).present? && event.content(:start_time) < Time.now }.then do |events|
|
36
|
+
- if events.any?
|
37
|
+
%ul
|
38
|
+
- repeater(events) do |event|
|
39
|
+
%li.list-style-none.py-4.border-bottom
|
40
|
+
= render Primer::FlexComponent.new(direction: :column, align_items: :start) do
|
41
|
+
- if event.content(:name).present?
|
42
|
+
= render(Primer::HeadingComponent.new(tag: :h3, flex: :auto)) { event.content(:name) }
|
43
|
+
= render Primer::HeadingComponent.new(tag: :h4, flex: :auto) do
|
44
|
+
- if event.content(:start_time).present?
|
45
|
+
= t(:'.time_and_place_html',
|
46
|
+
time: time_tag(event.content(:start_time), format: :ordinal_datetime_with_year),
|
47
|
+
place: event.content(:location).presence || t('.location_tbc'))
|
48
|
+
- else
|
49
|
+
= t(:'.time_and_place_html', time: t('.time_tbc'), place: event.content(:location).presence || t('.location_tbc'))
|
50
|
+
- if event.content(:description).present?
|
51
|
+
= render(Primer::TextComponent.new(mt: 1, color: :text_secondary)) { event.content.html(:description) }
|
52
|
+
- if event.content(:url).present?
|
53
|
+
= render Primer::ButtonComponent.new(tag: :a, href: event.content(:url), mt: 2) do
|
54
|
+
= render Primer::OcticonComponent.new('link-external')
|
55
|
+
= t :'.more_info'
|
56
|
+
- else
|
57
|
+
= render Primer::BlankslateComponent.new(title: t(:'.no_events'), icon: 'calendar')
|
58
|
+
- else
|
59
|
+
= render Primer::BlankslateComponent.new(title: t(:'.no_events'), icon: 'calendar')
|
@@ -0,0 +1,34 @@
|
|
1
|
+
- content_for :hero do
|
2
|
+
- cache [current_page, current_conference] do
|
3
|
+
= render Primer::BoxComponent.new(position: :relative, style: 'height: 639px') do
|
4
|
+
= render Primer::BoxComponent.new(position: :absolute, top: false, left: false, right: false, bottom: false,
|
5
|
+
style: 'background-color: var(--color-scale-blue-9)')
|
6
|
+
- if content(:gallery).present?
|
7
|
+
= render Primer::FlexComponent.new(position: :absolute, top: false, left: false, right: false, bottom: false, style: 'z-index: 1',
|
8
|
+
flex_direction: :column, justify_content: :center, align_items: :center,
|
9
|
+
data: { controller: :slideshow, slideshow_incrementer: 0, slideshow_advance: true }) do
|
10
|
+
- content(:gallery).each_with_index do |image, index|
|
11
|
+
= content.image_tag(image, { resize_to_limit: [1680, 1680] }, draggable: false, hidden: index != 0,
|
12
|
+
srcset: srcset(image, variant: { resize_to_limit: [1680, 1680] }),
|
13
|
+
style: 'object-fit: cover; max-width: max-content; max-height: max-content',
|
14
|
+
data: { slideshow_target: 'slide' }, class: %w[width-full height-full])
|
15
|
+
.container-lg.p-responsive.position-relative.color-text-white.height-full{ style: 'z-index: 2' }
|
16
|
+
= render Primer::BoxComponent.new(py: [3, nil, nil, 6]) do
|
17
|
+
%div{ style: 'text-shadow: 0 1px 1px #01040940, 0 1px 25px #010409bf;' }
|
18
|
+
- if current_conference.present?
|
19
|
+
= render(Primer::HeadingComponent.new(tag: :h1, classes: 'h000-mktg lh-condensed-ultra')) { current_conference.name }
|
20
|
+
= render Primer::TextComponent.new(tag: :address, classes: 'f2-light') do
|
21
|
+
= current_conference.institutions.collect(&:name).to_sentence
|
22
|
+
= render(Primer::TextComponent.new(tag: :time, classes: 'f2-light')) do
|
23
|
+
= t :'.dates_html', start_date: time_tag(current_conference.start_date, format: :day_and_month),
|
24
|
+
finish_date: time_tag(current_conference.finish_date, format: :day_and_month)
|
25
|
+
- else
|
26
|
+
= render(Primer::HeadingComponent.new(tag: :h1, classes: 'h000-mktg lh-condensed-ultra')) { Spina::Account.first.name }
|
27
|
+
- if current_conference.present? && current_conference.finish_date >= Date.today
|
28
|
+
= link_to t('.more_info'), frontend_conference_path(current_conference),
|
29
|
+
class: %w[btn-mktg btn-large-mktg btn-primary-mktg f3 mt-4]
|
30
|
+
- else
|
31
|
+
= link_to t('.more_info'), Spina::Page.find_by(name: 'about').materialized_path,
|
32
|
+
class: %w[btn-mktg btn-large-mktg btn-primary-mktg f3 mt-4]
|
33
|
+
%div{ style: 'text-shadow: 0 1px 1px rgba(var(--color-scale-black), 0.25), 0 1px 25px rgba(var(--color-scale-black), 0.75);' }
|
34
|
+
= render(Primer::MarkdownComponent.new(my: 4)) { content(:text).try(:html_safe) }
|
@@ -0,0 +1,7 @@
|
|
1
|
+
- content_for :breadcrumbs do
|
2
|
+
- if current_page.ancestors.any?
|
3
|
+
= ancestors
|
4
|
+
|
5
|
+
= render template: 'layouts/spina/conferences/primer_theme/application',
|
6
|
+
locals: { author: current_account.name, description: current_page.description,
|
7
|
+
seo_title: current_page.seo_title, title: current_page.title }
|
@@ -0,0 +1,40 @@
|
|
1
|
+
!!!
|
2
|
+
%html{ lang: I18n.locale, data: { color_mode: 'auto', light_theme: 'light', dark_theme: 'dark' } }
|
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: t(:'.title', title: title, suffix: current_account.name) }
|
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= t(:'.title', title: seo_title, suffix: current_account.name)
|
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
|
+
= javascript_include_tag 'turbo', type: 'module'
|
19
|
+
%script{ type: 'module', src: asset_path('@github/details-dialog-element/dist/index.js') }
|
20
|
+
%script{ type: 'module', src: asset_path('@github/include-fragment-element/dist/index.js') }
|
21
|
+
%script{ type: 'module', src: asset_path('@github/filter-input-element/dist/index.js') }
|
22
|
+
%script{ type: 'module', src: asset_path('@github/details-menu-element/dist/index.js') }
|
23
|
+
= yield :head
|
24
|
+
%body
|
25
|
+
- if current_spina_user.present?
|
26
|
+
.admin= render 'spina/shared/admin_bar'
|
27
|
+
%header= render 'navigation'
|
28
|
+
- unless local_assigns[:hide_alert]
|
29
|
+
= render 'current_conference_alert'
|
30
|
+
- if content_for? :flash
|
31
|
+
.flash-messages= yield :flash
|
32
|
+
%main
|
33
|
+
= yield :hero
|
34
|
+
- if content_for? :breadcrumbs
|
35
|
+
.container-lg.p-responsive.mt-4= yield :breadcrumbs
|
36
|
+
= yield :header
|
37
|
+
.container-lg.p-responsive.mt-4= yield
|
38
|
+
%footer
|
39
|
+
.container-lg.p-responsive.py-4= render 'footer'
|
40
|
+
= render 'spina/shared/social'
|