diff --git a/Gemfile b/Gemfile index 5f4eb874c03b9e0acd04305ebdac4f9e272cdfa2..058071e7a882f1dae15fc5a8406e367905af992b 100644 --- a/Gemfile +++ b/Gemfile @@ -22,6 +22,7 @@ gem 'devise' gem 'devise-i18n' gem 'enum_help' gem 'faceted_search'#, path: '../../noesya/faceted_search' +gem 'font-awesome-sass' gem 'front_matter_parser' gem 'gdpr' gem 'gitlab' diff --git a/Gemfile.lock b/Gemfile.lock index c301b7f8d6431020bd68d4adede012b6747e7e5c..f68a1b86079efedff13de3d109816d63c872f48b 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -514,6 +514,7 @@ DEPENDENCIES enum_help faceted_search figaro + font-awesome-sass front_matter_parser gdpr gitlab diff --git a/app/assets/stylesheets/admin/appstack.sass b/app/assets/stylesheets/admin/appstack.sass index a975819cbafa158990d1218d0dc63e4915d464a8..06e674993f421ad82117422b524ea86c91d90846 100644 --- a/app/assets/stylesheets/admin/appstack.sass +++ b/app/assets/stylesheets/admin/appstack.sass @@ -8,4 +8,5 @@ @import 'cropperjs/dist/cropper' @import 'gdpr/cookie_consent' @import '../commons/*' +@import 'commons/*' @import 'appstack/*' diff --git a/app/assets/stylesheets/admin/appstack/preview.sass b/app/assets/stylesheets/admin/commons/preview.sass similarity index 100% rename from app/assets/stylesheets/admin/appstack/preview.sass rename to app/assets/stylesheets/admin/commons/preview.sass diff --git a/app/assets/stylesheets/admin/appstack/treeview.sass b/app/assets/stylesheets/admin/commons/treeview.sass similarity index 98% rename from app/assets/stylesheets/admin/appstack/treeview.sass rename to app/assets/stylesheets/admin/commons/treeview.sass index 006dc95a0555e586cc8307a81eab149eaeaa2c24..b683239ec23342067392afe950424531d9a0617f 100644 --- a/app/assets/stylesheets/admin/appstack/treeview.sass +++ b/app/assets/stylesheets/admin/commons/treeview.sass @@ -1,6 +1,7 @@ .treeview &__element - + a + text-decoration: none & > .treeview__children .treeview__empty display: none diff --git a/app/assets/stylesheets/admin/pure.sass b/app/assets/stylesheets/admin/pure.sass index f1cdaba01f3091dd66dd11a6ae880785f3924eaf..976a811f1c90f8230e72ad0b9d754dd9ee8da2cd 100644 --- a/app/assets/stylesheets/admin/pure.sass +++ b/app/assets/stylesheets/admin/pure.sass @@ -1,6 +1,8 @@ @import 'pure/fonts' @import 'pure/variables' @import 'bootstrap' +@import 'bootstrap-icons/font/bootstrap-icons' +@import 'font-awesome' @import 'notyf/notyf.min' @import 'simple_form_password_with_hints' @import 'simple_form_bs5_file_input' @@ -8,4 +10,5 @@ @import 'cropperjs/dist/cropper' @import 'gdpr/cookie_consent' @import '../commons/*' +@import 'commons/*' @import 'pure/style' diff --git a/app/assets/stylesheets/admin/pure/style.sass b/app/assets/stylesheets/admin/pure/style.sass index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..2d13409c79a2bad6b1e78f2b97247f17073bb8ce 100644 --- a/app/assets/stylesheets/admin/pure/style.sass +++ b/app/assets/stylesheets/admin/pure/style.sass @@ -0,0 +1,49 @@ +.navbar + position: absolute + left: 0 + right: 0 + .navbar-brand + img + width: 100px +#menu + position: fixed + top: 0 + left: 0 + right: 0 + bottom: 0 + background: black + color: white + z-index: 1000 + +.hero + padding-top: 150px + padding-bottom: 30px + background-color: $color-background-alt + margin-bottom: 30px + +.container-fluid + padding-right: var(--bs-gutter-x) + padding-left: var(--bs-gutter-x) + +a + transition: text-decoration 0.5s, color 0.5s + text-decoration: underline + text-decoration-thickness: 1px + text-underline-offset: 5px + text-decoration-color: adjust-color($primary, $alpha: -0.5) + &:hover + color: darken($primary, 10) + text-decoration-color: $primary + +.commands + background: black + position: fixed + bottom: 0 + left: 0 + right: 0 + +footer + min-height: 300px + a + text-decoration: none + color: white \ No newline at end of file diff --git a/app/assets/stylesheets/admin/pure/variables.sass b/app/assets/stylesheets/admin/pure/variables.sass index 0208b6e6f2fd3c55a2d5db4d686d8c1bb637d1ee..1886c85162b3f58d5440e7c7e4c2ff76390f70b8 100644 --- a/app/assets/stylesheets/admin/pure/variables.sass +++ b/app/assets/stylesheets/admin/pure/variables.sass @@ -1 +1,15 @@ $font-family-sans-serif: "Basier Square", sans-serif + +$primary: #001AFF +$color-background-alt: #F5F5F5 + +$grid-gutter-width: 30px + +$border-radius: 0 + +$card-spacer-y: 0 +$card-spacer-x: 0 +$card-border-width: 0 +$card-cap-bg: transparent + +$transition-collapse: height 0 \ No newline at end of file diff --git a/app/services/osuny/breadcrumbs_on_rails_builder.rb b/app/services/osuny/breadcrumbs_on_rails_builder.rb new file mode 100644 index 0000000000000000000000000000000000000000..db1e95cd3a7e2f089235f7b48dd2aa421fd516a3 --- /dev/null +++ b/app/services/osuny/breadcrumbs_on_rails_builder.rb @@ -0,0 +1,23 @@ +class Osuny::BreadcrumbsOnRailsBuilder < BreadcrumbsOnRails::Breadcrumbs::Builder + def render + return '' unless @elements.many? + html = '<nav aria-label="breadcrumb"><ol class="breadcrumb m-0">' + html += @elements.collect do |element| + render_element(element) + end.join('') + html += '</ol></nav>' + html + end + + def render_element(element) + if element.path == nil + content = compute_name(element) + else + content = @context.link_to_unless_current(compute_name(element), compute_path(element), element.options) + end + classes = 'breadcrumb-item' + current_page = @context.current_page? compute_path(element) + classes += ' active' if current_page + "<li class=\"#{classes}\"#{' aria-current="page"' if current_page}>#{content}</li>" + end +end diff --git a/app/services/osuny/simple_navigation_renderer.rb b/app/services/osuny/simple_navigation_renderer.rb new file mode 100644 index 0000000000000000000000000000000000000000..eac009fd85cc9fd50c5bbf582c1e2da73927929a --- /dev/null +++ b/app/services/osuny/simple_navigation_renderer.rb @@ -0,0 +1,51 @@ +class Osuny::SimpleNavigationRenderer < SimpleNavigation::Renderer::Base + def render(item_container) + content = '<ul class="sidebar-nav">' + item_container.items.each do |item| + content << make(item) + end + content << '</ul>' + content.html_safe + end + + protected + + def make(item) + kind = item.send(:options)[:kind] + kind == :header ? make_header(item) + : make_item(item) + end + + def make_item(item) + li = "<li class=\"sidebar-item #{ item.html_options[:class] } #{ ' disabled' unless item.url }\">" + li += make_a(item) + li += make_subnavigation(item) if consider_sub_navigation?(item) + li += '</li>' + li + end + + def make_header(item) + icon = item.send(:options)[:icon] + header = '<li class="sidebar-header">' + header += "<i class=\"fas fa-#{ icon }\"></i>" if icon + header += item.name + header += '</li>' + header + end + + def make_a(item) + icon = item.send(:options)[:icon] + a = "<a href=\"#{ item.url }\" class=\"sidebar-link#{ item.selected? ? '' : ' collapsed' }\"" + a += " data-bs-target=\"##{ item.key }\" data-bs-toggle=\"collapse\"" if consider_sub_navigation?(item) + a += ">" + a += "<i class=\"fas fa-#{ icon }\"></i>" if icon + a += "<span class=\"align-middle\">#{ item.name }</span></a>" + a + end + + def make_subnavigation(item) + "<ul id=\"#{ item.key }\" class=\"sidebar-dropdown list-unstyled #{ item.selected? ? 'show' : 'collapse' }\"> + #{ render_sub_navigation_for item } + </ul>" + end +end diff --git a/app/views/admin/layouts/themes/_pure.html.erb b/app/views/admin/layouts/themes/_pure.html.erb index 91f1e15b30b21a6be9f6aab6da0d79942407dbfa..4f798216e65c229e1b6aef34eb402d2013203c06 100644 --- a/app/views/admin/layouts/themes/_pure.html.erb +++ b/app/views/admin/layouts/themes/_pure.html.erb @@ -13,7 +13,6 @@ </div> <% end %> <div class="d-flex justify-content-between"> - <h1><%= yield :title %></h1> <p class="text-end pt-1"><%= yield :title_right %></p> </div> <%= yield %> diff --git a/app/views/admin/layouts/themes/pure/_commands.html.erb b/app/views/admin/layouts/themes/pure/_commands.html.erb index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..452c75a6a56e34ec7ef7533aae57b5c9ae4a7941 100644 --- a/app/views/admin/layouts/themes/pure/_commands.html.erb +++ b/app/views/admin/layouts/themes/pure/_commands.html.erb @@ -0,0 +1,12 @@ +<% if content_for?(:action_bar_left) or content_for?(:action_bar_right) %> + <div class="commands"> + <div class="container-fluid py-3 d-flex"> + <div> + <%= yield :action_bar_left %> + </div> + <div class="ms-auto"> + <%= yield :action_bar_right %> + </div> + </div> + </div> +<% end %> \ No newline at end of file diff --git a/app/views/admin/layouts/themes/pure/_footer.html.erb b/app/views/admin/layouts/themes/pure/_footer.html.erb index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..155c826c4dbf0599650dd265435d1157348dbfcc 100644 --- a/app/views/admin/layouts/themes/pure/_footer.html.erb +++ b/app/views/admin/layouts/themes/pure/_footer.html.erb @@ -0,0 +1,31 @@ +<footer class="bg-black py-5 mt-5"> + <div class="container-fluid"> + <div class="row"> + <div class="col-md-3"> + <%= link_to 'https://www.osuny.org', target: :_blank do %> + <%= image_tag 'osuny-white.svg', width: 100 %> + <% end %> + </div> + <div class="col-md-9 text-md-end small"> + <ul class="list-inline"> + <li class="list-inline-item"> + <%= link_to 'API', api_root_path %> + </li> + <% + [ + :terms_of_service, + :privacy_policy, + :cookies_policy + ].each do |term| %> + <li class="list-inline-item"> + <%= link_to t("#{term}"), t("#{term}_url"), target: '_blank', rel: 'noreferrer' %> + </li> + <% end %> + <li class="list-inline-item"> + <%= link_to t('cookies_consent_choice'), '', class: 'js-gdpr__cookie_consent__display_again' %> + </li> + </ul> + </div> + </div> + </div> +</footer> \ No newline at end of file diff --git a/app/views/admin/layouts/themes/pure/_hero.html.erb b/app/views/admin/layouts/themes/pure/_hero.html.erb index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..87d355c0df695db499b0e590264397ba04f22fda 100644 --- a/app/views/admin/layouts/themes/pure/_hero.html.erb +++ b/app/views/admin/layouts/themes/pure/_hero.html.erb @@ -0,0 +1,6 @@ +<div class="hero"> + <div class="container-fluid"> + <h1><%= yield :title %></h1> + <%= render_breadcrumbs builder: Osuny::BreadcrumbsOnRailsBuilder %> + </div> +</div> \ No newline at end of file diff --git a/app/views/admin/layouts/themes/pure/_nav.html.erb b/app/views/admin/layouts/themes/pure/_nav.html.erb index e980b4ea157ce811aa1076537f2b29ebd0f690f3..df7702820af6d6aed18808cd9caa91d72ce41fbf 100644 --- a/app/views/admin/layouts/themes/pure/_nav.html.erb +++ b/app/views/admin/layouts/themes/pure/_nav.html.erb @@ -1,6 +1,61 @@ -<nav> - <%= link_to admin_root_path, class: 'sidebar-brand' do %> - <%= image_tag 'osuny-black.svg', class: 'img-fluid' %> - <% end %> - <%= render_navigation context: :admin %> -</nav> \ No newline at end of file +<nav class="navbar navbar-main navbar-light bg-transparent" aria-label="Navigation"> + <div class="container-fluid"> + <%= link_to admin_root_path, class: 'navbar-brand' do %> + <%= image_tag 'osuny-black.svg', class: 'img-fluid' %> + <% end %> + <button class="btn-open bg-transparent border-0" + type="button" + data-bs-toggle="collapse" + data-bs-target="#menu" + data-bs-animation="" + aria-controls="navbar-brand" + aria-expanded="false" + aria-label="Afficher la navigation"> + Menu + <span class="navbar-toggler-icon"></span> + </button> + </div> +</nav> +<div class="collapse" id="menu"> + <div class="container-fluid"> + <div class="d-flex"> + <%= link_to admin_root_path, class: 'navbar-brand' do %> + <%= image_tag 'osuny-white.svg', class: 'img-fluid', width: 100 %> + <% end %> + <button class="btn-close border-0 text-white" + type="button" + data-bs-toggle="collapse" + data-bs-target="#menu" + aria-controls="navbar-brand" + aria-expanded="false" + aria-label="Afficher/masquer la navigation"> + Fermer + <span class="navbar-close-icon"></span> + </button> + </div> + <div class="nav-content pt-5"> + <%= render_navigation context: :admin, renderer: Osuny::SimpleNavigationRenderer %> + <ul class="navbar-nav navbar-align"> + <li class="nav-item dropdown"> + <a class="nav-link dropdown-toggle d-none d-sm-inline-block js-user-dropdown-toggle" href="#" data-bs-toggle="dropdown"> + <span class="text-dark"><%= current_user.to_s %></span> + </a> + <div class="dropdown-menu dropdown-menu-end"> + <%= link_to t('menu.profile'), edit_user_registration_path, class: 'dropdown-item' %> + <%= link_to t('menu.server_admin'), server_root_path, class: 'dropdown-item' if current_user.server_admin? %> + <%= link_to t('menu.sign_out'), destroy_user_session_path, method: :delete, class: 'dropdown-item' %> + </div> + </li> + <li> + <a class="nav-link nav-link--last js-user-button" href="#"> + <% if current_user.picture.attached? && current_user.picture.variable? %> + <%= image_tag current_user.picture.variant(resize: '80x80'), class: 'avatar img-fluid rounded-circle' %> + <% else %> + <%= image_tag 'avatar.jpg', class: 'avatar img-fluid rounded-circle' %> + <% end %> + </a> + </li> + </ul> + </div> + </div> +</div>