2020-01-22 14:34:45 +01:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
2020-02-26 10:19:43 +01:00
|
|
|
# Stylesheet is a cached CSS file that allows to easily customize the interface of Fab-manager with some configurable colors and
|
2020-01-22 14:34:45 +01:00
|
|
|
# a picture for the background of the user's profile.
|
|
|
|
# There's only one stylesheet record in the database, which is updated on each colour change.
|
2020-03-25 10:16:47 +01:00
|
|
|
class Stylesheet < ApplicationRecord
|
2020-05-04 13:20:57 +02:00
|
|
|
|
|
|
|
# brightness limits to change the font color to black or white
|
2020-05-05 16:20:44 +02:00
|
|
|
BRIGHTNESS_HIGH_LIMIT = 160
|
2020-05-04 13:20:57 +02:00
|
|
|
BRIGHTNESS_LOW_LIMIT = 40
|
|
|
|
|
2016-03-23 18:39:41 +01:00
|
|
|
validates_presence_of :contents
|
|
|
|
|
2020-05-04 12:08:43 +02:00
|
|
|
## ===== COMMON =====
|
2018-12-18 10:21:35 +01:00
|
|
|
|
2020-01-27 17:10:29 +01:00
|
|
|
def rebuild!
|
|
|
|
if Stylesheet.primary && Stylesheet.secondary && name == 'theme'
|
|
|
|
update(contents: Stylesheet.css)
|
|
|
|
elsif name == 'home_page'
|
|
|
|
update(contents: Stylesheet.home_page_css)
|
|
|
|
end
|
2016-03-23 18:39:41 +01:00
|
|
|
end
|
|
|
|
|
2020-05-04 12:08:43 +02:00
|
|
|
## ===== THEME =====
|
|
|
|
|
|
|
|
def self.build_theme!
|
2018-12-17 16:02:02 +01:00
|
|
|
return unless Stylesheet.primary && Stylesheet.secondary
|
|
|
|
|
2020-01-27 17:10:29 +01:00
|
|
|
if Stylesheet.theme
|
|
|
|
Stylesheet.theme.rebuild!
|
2018-12-17 16:02:02 +01:00
|
|
|
else
|
2020-01-27 17:10:29 +01:00
|
|
|
Stylesheet.create!(contents: Stylesheet.css, name: 'theme')
|
2016-03-23 18:39:41 +01:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def self.primary
|
2020-05-13 15:02:03 +02:00
|
|
|
Setting.get('main_color')
|
2016-03-23 18:39:41 +01:00
|
|
|
end
|
|
|
|
|
|
|
|
def self.secondary
|
2020-05-13 15:02:03 +02:00
|
|
|
Setting.get('secondary_color')
|
2016-03-23 18:39:41 +01:00
|
|
|
end
|
|
|
|
|
|
|
|
def self.primary_light
|
2018-12-17 16:02:02 +01:00
|
|
|
Stylesheet.primary.paint.lighten(10)
|
2016-03-23 18:39:41 +01:00
|
|
|
end
|
|
|
|
|
|
|
|
def self.primary_dark
|
2018-12-17 16:02:02 +01:00
|
|
|
Stylesheet.primary.paint.darken(20)
|
2016-03-23 18:39:41 +01:00
|
|
|
end
|
|
|
|
|
|
|
|
def self.secondary_light
|
2018-12-17 16:02:02 +01:00
|
|
|
Stylesheet.secondary.paint.lighten(10)
|
2016-03-23 18:39:41 +01:00
|
|
|
end
|
|
|
|
|
|
|
|
def self.secondary_dark
|
2018-12-17 16:02:02 +01:00
|
|
|
Stylesheet.secondary.paint.darken(20)
|
2016-03-23 18:39:41 +01:00
|
|
|
end
|
|
|
|
|
|
|
|
def self.primary_with_alpha(alpha)
|
2018-12-17 16:02:02 +01:00
|
|
|
Stylesheet.primary.paint.to_rgb.insert(3, 'a').insert(-2, ", #{alpha}")
|
2016-03-23 18:39:41 +01:00
|
|
|
end
|
|
|
|
|
2020-01-27 17:10:29 +01:00
|
|
|
def self.theme
|
|
|
|
Stylesheet.find_by(name: 'theme')
|
|
|
|
end
|
|
|
|
|
2020-05-04 13:20:57 +02:00
|
|
|
def self.primary_text_color
|
|
|
|
Stylesheet.primary.paint.brightness >= BRIGHTNESS_HIGH_LIMIT ? 'black' : 'white'
|
|
|
|
end
|
|
|
|
|
|
|
|
def self.primary_decoration_color
|
|
|
|
Stylesheet.primary.paint.brightness <= BRIGHTNESS_LOW_LIMIT ? 'white' : 'black'
|
|
|
|
end
|
|
|
|
|
|
|
|
def self.secondary_text_color
|
|
|
|
Stylesheet.secondary.paint.brightness <= BRIGHTNESS_LOW_LIMIT ? 'white' : 'black'
|
|
|
|
end
|
|
|
|
|
2020-01-22 14:34:45 +01:00
|
|
|
def self.css # rubocop:disable Metrics/AbcSize
|
|
|
|
<<~CSS
|
|
|
|
.bg-red { background-color: #{Stylesheet.primary}; }
|
|
|
|
.bg-red-dark { background-color: #{Stylesheet.primary}; }
|
|
|
|
#nav .nav { background-color: #{Stylesheet.primary}; }
|
2020-05-04 13:20:57 +02:00
|
|
|
#nav .nav > li > a { color: #{Stylesheet.primary_text_color}; }
|
|
|
|
#nav .nav > li > a:hover, #nav .nav > li > a:focus { background-color: #{Stylesheet.primary_light}; color: #{Stylesheet.primary_text_color}; }
|
|
|
|
#nav .nav > li > a.active { border-left: 3px solid #{Stylesheet.primary_dark}; background-color: #{Stylesheet.primary_light}; color: #{Stylesheet.primary_text_color}; }
|
|
|
|
.nav-primary ul.nav > li.menu-spacer { background: linear-gradient(45deg, #{Stylesheet.primary_decoration_color}, transparent); }
|
|
|
|
.nav-primary .text-bordeau { color: #{Stylesheet.primary_decoration_color}; }
|
|
|
|
.btn-theme { background-color: #{Stylesheet.primary}; color: #{Stylesheet.primary_text_color}; }
|
|
|
|
.btn-theme:active, .btn-theme:hover { background-color: #{Stylesheet.primary_dark}; color: #{Stylesheet.primary_text_color}; }
|
|
|
|
.label-theme { background-color: #{Stylesheet.primary}; color: #{Stylesheet.primary_text_color}; }
|
2020-01-22 14:34:45 +01:00
|
|
|
.btn-link { color: #{Stylesheet.primary} !important; }
|
|
|
|
.btn-link:hover { color: #{Stylesheet.primary_dark} !important; }
|
|
|
|
a { color: #{Stylesheet.primary}; }
|
2020-10-28 12:10:25 +01:00
|
|
|
.about-page-link a.about-link, .user-profile-nav b.caret { color: #{Stylesheet.primary}; }
|
|
|
|
.app-generator a, .home-events h4 a, a.reinit-filters, .pricing-panel a, .calendar-url a, .article a, a.project-author, a.dsq-brlink, .alert a, .about-fablab a, a.collected-infos { color: #{Stylesheet.primary}; }
|
|
|
|
.app-generator a:hover, .home-events h4 a:hover, a.reinit-filters:hover, .pricing-panel a:hover, .calendar-url a:hover, .article a:hover, a.project-author:hover, a.dsq-brlink:hover, .widget .widget-content a:hover, .alert a:hover, .about-fablab a:hover, a.collected-infos:hover { color: #{Stylesheet.primary_dark}; }
|
|
|
|
.btn.btn-default.reserve-button, .btn.btn-default.show-button, .btn.btn-default.red { color: #{Stylesheet.primary} !important; }
|
|
|
|
.nav.nav-tabs .uib-tab.nav-item:not(.active) a { color: #{Stylesheet.primary}; }
|
|
|
|
.article h2, .article h3, .article h5 { color: #{Stylesheet.primary} !important; }
|
|
|
|
table.table thead tr th a, table.table tbody tr td a:not(.btn) { color: #{Stylesheet.primary}; }
|
|
|
|
table.table thead tr th a:hover, table.table tbody tr td a:not(.btn):hover { color: #{Stylesheet.primary_dark}; }
|
2020-01-22 14:34:45 +01:00
|
|
|
a:hover, a:focus { color: #{Stylesheet.primary_dark}; }
|
2020-10-28 12:10:25 +01:00
|
|
|
h2, h3, h3.red, h5 { color: #{Stylesheet.primary} !important; }
|
2020-01-22 14:34:45 +01:00
|
|
|
h5:after { background-color: #{Stylesheet.primary}; }
|
2020-05-04 13:20:57 +02:00
|
|
|
.bg-yellow { background-color: #{Stylesheet.secondary} !important; color: #{Stylesheet.secondary_text_color}; }
|
|
|
|
.event:hover { background-color: #{Stylesheet.primary}; color: #{Stylesheet.secondary_text_color}; }
|
2020-01-22 14:34:45 +01:00
|
|
|
.widget h3 { color: #{Stylesheet.primary}; }
|
|
|
|
.modal-header h1, .custom-invoice .modal-header h1 { color: #{Stylesheet.primary}; }
|
2020-05-04 13:20:57 +02:00
|
|
|
.block-link:hover, .fc-toolbar .fc-button:hover, .fc-toolbar .fc-button:active, .fc-toolbar .fc-button.fc-state-active { background-color: #{Stylesheet.secondary}; color: #{Stylesheet.secondary_text_color} !important; }
|
|
|
|
.block-link:hover .user-name { color: #{Stylesheet.secondary_text_color} !important; }
|
2020-01-22 14:34:45 +01:00
|
|
|
.carousel-control:hover, .carousel-control:focus, .carousel-caption .title a:hover { color: #{Stylesheet.secondary}; }
|
2020-05-04 13:20:57 +02:00
|
|
|
.well.well-warning { border-color: #{Stylesheet.secondary}; background-color: #{Stylesheet.secondary}; color: #{Stylesheet.secondary_text_color}; }
|
2020-01-22 14:34:45 +01:00
|
|
|
.text-yellow { color: #{Stylesheet.secondary} !important; }
|
|
|
|
.red { color: #{Stylesheet.primary} !important; }
|
2020-05-04 13:20:57 +02:00
|
|
|
.btn-warning, .editable-buttons button[type=submit].btn-primary { background-color: #{Stylesheet.secondary} !important; border-color: #{Stylesheet.secondary} !important; color: #{Stylesheet.secondary_text_color}; }
|
|
|
|
.btn-warning:hover, .editable-buttons button[type=submit].btn-primary:hover, .btn-warning:focus, .editable-buttons button[type=submit].btn-primary:focus, .btn-warning.focus, .editable-buttons button.focus[type=submit].btn-primary, .btn-warning:active, .editable-buttons button[type=submit].btn-primary:active, .btn-warning.active, .editable-buttons button.active[type=submit].btn-primary, .open > .btn-warning.dropdown-toggle, .editable-buttons .open > button.dropdown-toggle[type=submit].btn-primary { background-color: #{Stylesheet.secondary_dark} !important; border-color: #{Stylesheet.secondary_dark} !important; color: #{Stylesheet.secondary_text_color}; }
|
|
|
|
.btn-warning-full { border-color: #{Stylesheet.secondary}; background-color: #{Stylesheet.secondary}; color: #{Stylesheet.secondary_text_color} !important; }
|
|
|
|
.heading .heading-btn a:hover { background-color: #{Stylesheet.secondary}; color: #{Stylesheet.secondary_text_color}; }
|
2020-01-22 14:34:45 +01:00
|
|
|
.pricing-panel .content .wrap { border-color: #{Stylesheet.secondary}; }
|
2020-05-04 13:20:57 +02:00
|
|
|
.pricing-panel .cta-button .btn:hover, .pricing-panel .cta-button .custom-invoice .modal-body .elements li:hover, .custom-invoice .modal-body .elements .pricing-panel .cta-button li:hover { background-color: #{Stylesheet.secondary} !important; color: #{Stylesheet.secondary_text_color}; }
|
2020-01-22 14:34:45 +01:00
|
|
|
a.label:hover, .form-control.form-control-ui-select .select2-choices a.select2-search-choice:hover, a.label:focus, .form-control.form-control-ui-select .select2-choices a.select2-search-choice:focus { color: #{Stylesheet.primary}; }
|
|
|
|
.about-picture { background: linear-gradient( rgba(255,255,255,0.12), rgba(255,255,255,0.13) ), linear-gradient( #{Stylesheet.primary_with_alpha(0.78)}, #{Stylesheet.primary_with_alpha(0.82)} ), url('/about-fablab.jpg') no-repeat; }
|
2020-05-04 13:20:57 +02:00
|
|
|
.social-icons > div:hover { background-color: #{Stylesheet.secondary}; color: #{Stylesheet.secondary_text_color}; }
|
2020-01-22 14:34:45 +01:00
|
|
|
.profile-top { background: linear-gradient( rgba(255,255,255,0.12), rgba(255,255,255,0.13) ), linear-gradient(#{Stylesheet.primary_with_alpha(0.78)}, #{Stylesheet.primary_with_alpha(0.82)} ), url('#{CustomAsset.get_url('profile-image-file') || '/about-fablab.jpg'}') no-repeat; }
|
2020-05-04 13:20:57 +02:00
|
|
|
.profile-top .social-links a:hover { background-color: #{Stylesheet.secondary} !important; border-color: #{Stylesheet.secondary} !important; color: #{Stylesheet.secondary_text_color}; }
|
|
|
|
section#cookies-modal div.cookies-consent .cookies-actions button.accept { background-color: #{Stylesheet.secondary}; color: #{Stylesheet.secondary_text_color}; }
|
2020-01-22 14:34:45 +01:00
|
|
|
CSS
|
2016-03-23 18:39:41 +01:00
|
|
|
end
|
2020-01-27 17:10:29 +01:00
|
|
|
|
|
|
|
## ===== HOME PAGE =====
|
|
|
|
|
|
|
|
def self.home_style
|
2020-05-13 15:02:03 +02:00
|
|
|
style = Setting.get('home_css')
|
2020-01-27 17:10:29 +01:00
|
|
|
".home-page { #{style} }"
|
|
|
|
end
|
|
|
|
|
|
|
|
def self.build_home!
|
|
|
|
if Stylesheet.home_page
|
|
|
|
Stylesheet.home_page.rebuild!
|
|
|
|
else
|
|
|
|
Stylesheet.create!(contents: Stylesheet.home_page_css, name: 'home_page')
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def self.home_page
|
|
|
|
Stylesheet.find_by(name: 'home_page')
|
|
|
|
end
|
|
|
|
|
|
|
|
def self.home_page_css
|
|
|
|
engine = Sass::Engine.new(home_style, syntax: :scss)
|
|
|
|
engine.render.presence || '.home-page {}'
|
|
|
|
end
|
2016-03-23 18:39:41 +01:00
|
|
|
end
|