diff --git a/app/assets/stylesheets/application.css b/app/assets/stylesheets/application.css index db853e7..1f54317 100644 --- a/app/assets/stylesheets/application.css +++ b/app/assets/stylesheets/application.css @@ -1,21 +1,25 @@ /* - * This is a manifest file that'll be compiled into application.css, which will include all the files - * listed below. + * This is a manifest file that'll be compiled into application.css, which will + * include all the files listed below. * - * Any CSS (and SCSS, if configured) file within this directory, lib/assets/stylesheets, or any plugin's - * vendor/assets/stylesheets directory can be referenced here using a relative path. + * Any CSS (and SCSS, if configured) file within this directory, + * lib/assets/stylesheets, or any plugin's vendor/assets/stylesheets directory + * can be referenced here using a relative path. * - * You're free to add application-wide styles to this file and they'll appear at the bottom of the - * compiled file so the styles you add here take precedence over styles defined in any other CSS - * files in this directory. Styles in this file should be added after the last require_* statement. - * It is generally better to create a new file per style scope. + * You're free to add application-wide styles to this file and they'll appear at + * the bottom of the compiled file so the styles you add here take precedence + * over styles defined in any other CSS files in this directory. Styles in this + * file should be added after the last require_* statement. It is generally + * better to create a new file per style scope. * *= require_tree . *= require_self */ -* { - font-family: system-ui; +*, +::before, +::after { + box-sizing: border-box; } ::selection { background-color: #009ade; @@ -24,28 +28,67 @@ :focus-visible { outline: none; } -.centered { - margin: 0 auto; -} + body { - margin: 0 0.5rem; + display: grid; + gap: 0.8em; + grid-template-areas: + "header header header" + "nav nav nav" + "leftside main rightside"; + grid-template-columns: 1fr 0fr 1fr; + grid-template-rows: repeat(3, auto); + font-family: system-ui; + margin: 0.4em; } +button, +input, +select { + background-color: inherit; + font: inherit; +} + /* blue - target for interaction with pointer */ /* gray - target for interaction with keyboard */ -input, -select { - background-color: white; - border: 1px solid; - border-radius: 0.2rem; - border-color: #cccccc; +a, +button, +input[type=submit] { + align-items: center; + color: #a0a0a0; + cursor: pointer; + fill: #a0a0a0; + font-weight: bold; + text-decoration: none; } -input:not([type=checkbox]), +.button, +button, +input[type=submit] { + display: flex; + font-size: 0.8rem; + padding: 0.4em; + width: fit-content; +} +input:not([type=submit]).not([type=checkbox]), select { - font-size: 0.9rem; padding: 0.2rem 0.4rem; } +.button, +button, +input, +select { + border: solid 1px #a0a0a0; + border-radius: 0.25em; +} +.button > svg, +.tab > svg, +button > svg { + height: 1.8em; + padding-right: 0.4em; + width: 1.8em; +} + input[type=checkbox] { accent-color: #009ade; appearance: none; @@ -83,72 +126,52 @@ input:read-only:hover { background: white; } -.app-menu { - height: 2.2rem; - margin: 0.4rem 0; -} -.app-menu > * { - float: right; - margin-left: 0.8rem; + +.header { + display: flex; + gap: 0.8em; + grid-area: header; + justify-content: flex-end; } -.nav-menu { - height: 2.4rem; - margin: 0.4rem 0; + +.navigation { + display: flex; + grid-area: nav; } -.nav-menu .right > * { - float: right; -} -.nav-menu .left > * { - float: left; +.navigation > .tab + .tab.right { + margin-inline-start: 4%; } /* TODO: inactive tab color #d0d0d0 or #c7c7c7 */ -.nav-menu .tab { - border: none; - border-bottom: solid 0.2rem #a0a0a0; - border-radius: 0; - font-size: 0.9rem; - padding: 0.5rem 0.8rem; +.navigation > .tab { + border-bottom: solid 3px #c7c7c7; + display: flex; + flex: 1; + font-size: 1rem; + justify-content: center; + padding-block: 0.3em; } -.nav-menu .tab:hover { - border-bottom: solid 0.2rem #009ade; +.navigation > .tab:hover { + border-bottom: solid 4px #009ade; } -.nav-menu .tab.active { - border-bottom: solid 0.2rem; +.navigation > .tab.active { + border-bottom: solid 4px; color: #009ade; fill: #009ade; } -.nav-menu a.button svg, -.nav-menu button svg { - height: 1.5rem; - padding-right: 0.4rem; - width: 1.5rem; + + +.leftside { + grid-area: leftside; +} +.main { + grid-area: main; +} +.rightside { + grid-area: rightside; } -a.button, -button, -input[type=submit] { - align-items: center; - background-color: white; - border: 1px solid; - border-color: #a0a0a0; - border-radius: 0.2rem; - color: #a0a0a0; - cursor: pointer; - display: flex; - fill: #a0a0a0; - font-size: 0.8rem; - font-weight: bold; - padding: 0.4rem; - text-decoration: none; - width: fit-content; -} -a.button svg, -button svg { - height: 1.3rem; - padding-right: 0.4rem; - width: 1.3rem; -} + a.button:hover, a.button.active:hover, button:hover, @@ -180,6 +203,7 @@ button.dangerous:hover:focus-visible { border-color: #b21237; } + .flashes { height: 2.1rem; } @@ -226,6 +250,7 @@ button.dangerous:hover:focus-visible { opacity: 1; } + form table { border-spacing: 0.8rem; } @@ -264,41 +289,41 @@ form input[type=submit] { padding: 0.75rem; } + table.items { border-spacing: 0; - border: 1px solid #dddddd; - border-radius: 0.2rem; + border: solid 1px #dddddd; + border-radius: 0.25em; font-size: 0.85rem; - margin: 1rem auto 0 auto; + text-align: center; } table.items thead { font-size: 0.8rem; - line-height: 2.2rem; } table.items thead, table.items tbody tr:hover { background-color: #f3f3f3; } +table.items th { + padding-block: 0.75em; +} table.items th, table.items td { - padding: 0 0.8rem; - text-align: center; + padding-inline-start: 0.8rem; +} +table.items th:last-child { + padding-inline-end: 0.4em; } table.items td { - border-top: 1px solid #dddddd; + border-top: solid 1px #dddddd; + padding-block: 0.1em; } table.items td:first-child { - padding: 0; text-align: left; } table.items a { - color: black; - cursor: pointer; - display: block; - font-weight: normal; - line-height: 2.2rem; - padding: 0 0.8rem; - text-decoration: none; + color: inherit; + font: inherit; } table.items a:hover, table.items a:focus-visible, @@ -329,13 +354,13 @@ table.items td.number { text-align: right; } table.items td.actions { - padding: 0 0 0 0.8rem; text-align: right; } -table.items button { +table.items .button, +table.items button, +table.items input[type=submit] { font-weight: normal; - margin-right: 0.25rem; - padding: 0.25rem; + padding: 0.3em; } table.items select:not(:hover), table.items button:not(:hover) { @@ -347,7 +372,10 @@ table.items select:focus-visible { color: black; } -.contextual { - float: right; - margin-top: 1rem; + +.centered { + margin: 0 auto; +} +.unwrappable { + white-space: nowrap; } diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 70f8338..70c60a5 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -54,14 +54,6 @@ module ApplicationHelper form_for(record, **options, &-> (f) { f.table_form_for(&block) }) end - def image_button_to(name, image = nil, options = nil, html_options = {}) - image_element_to(:button, name, image, options, html_options) - end - - def image_link_to(name, image = nil, options = nil, html_options = {}) - image_element_to(:link, name, image, options, html_options) - end - def svg_tag(source, options = {}) content_tag :svg, options do tag.use href: image_path(source + ".svg") + "#icon" @@ -69,30 +61,47 @@ module ApplicationHelper end def navigation_menu - menu_items = {right: [ + menu_items = [ + #[".test", "weight-kilogram", units_path, :restricted], + [".units", "weight-kilogram", units_path, :restricted, 'right'], [".users", "account-multiple-outline", users_path, :admin], - [".units", "weight-kilogram", units_path, :restricted], - ]} + ] - menu_items.map do |alignment, items| - content_tag :div, class: alignment do - items.map do |label, image, path, status| - if current_user.at_least(status) - image_link_to t(label), image, path, class: "tab", current: :active - end - end.join.html_safe + menu_items.map do |label, image, path, status, css_class| + if current_user.at_least(status) + image_tab_to t(label), image, path, class: "tab #{css_class}", current: :active end end.join.html_safe end + def image_button_to(name, image = nil, options = nil, html_options = {}) + html_options[:class] = class_names(html_options[:class], 'button') + image_element_to(:button, name, image, options, html_options) + end + + def image_link_to(name, image = nil, options = nil, html_options = {}) + html_options[:class] = class_names(html_options[:class], 'button') + image_element_to(:link, name, image, options, html_options) + end + + def image_tab_to(name, image = nil, options = nil, html_options = {}) + image_element_to(:link, name, image, options, html_options) + end + + private def image_element_to(type, name, image = nil, options = nil, html_options = {}) - current = (url_for(options) == request.path) && html_options.delete(:current) - return "" if current == :hide + current = html_options.delete(:current) + current = nil unless url_for(options) == request.path + return '' if current == :hide name = svg_tag("pictograms/#{image}") + name if image - html_options[:class] = class_names(html_options[:class], "button", active: current == :active) + html_options[:class] = class_names( + html_options[:class], + active: current == :active, + dangerous: html_options[:method] == :delete + ) if html_options[:onclick]&.is_a? Hash html_options[:onclick] = "return confirm('#{html_options[:onclick][:confirm]}');" end diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index d8b9f58..800bb5c 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -11,23 +11,24 @@ -
+
<% if user_signed_in? %> + <%= image_link_to current_user.email, "account-wrench-outline", + edit_user_registration_path, current: :hide %> <% if current_user_disguised? %> <%= image_button_to t(".revert"), "incognito-off", revert_users_path %> <% else %> <%= image_button_to t(".sign_out"), "logout", destroy_user_session_path, method: :delete %> <% end %> - <%= image_link_to current_user.email, "account-wrench-outline", - edit_user_registration_path, current: :hide %> <% else %> + <%= image_link_to t(:sign_in), "login", new_user_session_path, current: :hide %> <%= image_link_to t(:register), "account-plus-outline", new_user_registration_path, current: :hide %> - <%= image_link_to t(:sign_in), "login", new_user_session_path, current: :hide %> <% end %> -
+ + <%# Allow overwriting/clearing navigation menu for some views %> - + <%= yield %> diff --git a/app/views/units/index.html.erb b/app/views/units/index.html.erb index 4511a70..4a6e500 100644 --- a/app/views/units/index.html.erb +++ b/app/views/units/index.html.erb @@ -1,10 +1,12 @@ -
+
<% if current_user.at_least(:active) %> <%= image_link_to t(".add_unit"), "plus-outline", new_unit_path %> <% end %>
- +<%#= turbo_frame_tag 'unit_form' %> + +
@@ -18,8 +20,9 @@ <% Unit.each_with_level(@units) do |unit, level| %> - diff --git a/app/views/users/index.html.erb b/app/views/users/index.html.erb index 1445f9d..56df7b4 100644 --- a/app/views/users/index.html.erb +++ b/app/views/users/index.html.erb @@ -1,10 +1,10 @@ -
<%= User.human_attribute_name(:symbol).capitalize %>
0 %>> - <%= link_to unit.symbol, edit_unit_path(unit) %> + + <%= link_to unit.symbol, edit_unit_path(unit), + {style: level > 0 ? 'padding-left:0.6em;': ''} %> <%= unit.name %> <%= scientifize(unit.multiplier) unless unit.multiplier == 1 %>
+
- + diff --git a/app/views/users/registrations/edit.html.erb b/app/views/users/registrations/edit.html.erb index 0082e45..a577576 100644 --- a/app/views/users/registrations/edit.html.erb +++ b/app/views/users/registrations/edit.html.erb @@ -1,11 +1,11 @@ <% content_for :navigation, flush: true do %>
- <%= image_link_to t(:back), "arrow-left-bold-outline", + <%= image_link_to t(:back), 'arrow-left-bold-outline', request.referer.present? ? :back : root_url %>
<%= image_button_to t(".delete"), "account-remove-outline", user_registration_path, - class: "dangerous", method: :delete, onclick: {confirm: t(".confirm_delete")} %> + method: :delete, onclick: {confirm: t(".confirm_delete")} %>
<% end %> diff --git a/app/views/users/sessions/new.html.erb b/app/views/users/sessions/new.html.erb index 2eed7cf..0c96438 100644 --- a/app/views/users/sessions/new.html.erb +++ b/app/views/users/sessions/new.html.erb @@ -10,4 +10,4 @@ <% end %> <%= content_tag :p, t(:or), style: "text-align: center;" %> -<%= image_link_to t(:recover_password), "lock-reset", new_user_password_path, class: "centered" %> +<%= image_link_to t(:recover_password), 'lock-reset', new_user_password_path, class: 'centered' %>
<%= User.human_attribute_name(:email).capitalize %> <%= User.human_attribute_name(:status).capitalize %> <%= User.human_attribute_name(:confirmed_at).capitalize %><%= User.human_attribute_name(:created_at).capitalize %> UTC<%= User.human_attribute_name(:created_at).capitalize %> UTC <%= t :actions %>