Badges page redesign (#18419)
* Badges homepage redesign * badges.scss * Attempt at solving badge ci check * Added badge prompt * Merged with main * Removed /badge/.. related code * Revert removing badge page * Fixed Safari design issue * Removed not-requried css property * Trying to remove /badge/ * Updated profile badges * Fixed userprofile badge * Accessibility changes + removed failed tests * Tests passed
This commit is contained in:
parent
01513bae69
commit
f1176900f0
9 changed files with 51 additions and 89 deletions
|
|
@ -12,11 +12,6 @@ class Badge < ApplicationRecord
|
|||
validates :title, presence: true, uniqueness: true
|
||||
|
||||
before_validation :generate_slug
|
||||
after_save :bust_path
|
||||
|
||||
def path
|
||||
"/badge/#{slug}"
|
||||
end
|
||||
|
||||
def self.id_for_slug(slug)
|
||||
select(:id).find_by(slug: slug)&.id
|
||||
|
|
@ -27,10 +22,4 @@ class Badge < ApplicationRecord
|
|||
def generate_slug
|
||||
self.slug = CGI.escape(title.to_s).parameterize
|
||||
end
|
||||
|
||||
def bust_path
|
||||
cache_bust = EdgeCache::Bust.new
|
||||
cache_bust.call(path)
|
||||
cache_bust.call("#{path}?i=i")
|
||||
end
|
||||
end
|
||||
|
|
|
|||
16
app/views/badges/_badge_detail.html.erb
Normal file
16
app/views/badges/_badge_detail.html.erb
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
<div class="grid grid-cols-1 gap-1 s:gap-8 s:grid-cols-2">
|
||||
<img
|
||||
style="width: 192px; height: 192px; background-color: #FAFAFA; border-radius: 8px; border: 1px solid #F5F5F5;"
|
||||
class="flex flex-row p-3"
|
||||
src="<%= optimized_image_url(badge.badge_image_url, width: 192) %>"
|
||||
alt="<%= badge.title %> badge"
|
||||
title="<%= badge.title %>"
|
||||
loading="lazy" />
|
||||
<div class="flex flex-col justify-between items-start">
|
||||
<div class="flex flex-col items-start">
|
||||
<h4 class="fw-800 fs-l color-grey-800"><%= badge.title %></h4>
|
||||
<p><%= badge.description %></p>
|
||||
</div>
|
||||
<button class="flex flex-row items-start c-btn c-btn--primary" onclick="window.Forem.closeModal()">Got it</button>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -1,19 +1,33 @@
|
|||
<% title t("views.badges.meta.title") %>
|
||||
|
||||
<div class="blank-space"></div>
|
||||
<div class="container article">
|
||||
<h1 style="text-align: center;"><%= t("views.badges.heading") %></h1>
|
||||
<p style="text-align: center; max-width: 96%;"><%= t("views.badges.desc") %></p>
|
||||
<div class="body sticker-book">
|
||||
<main class="crayons-layout px-2 l:px-2">
|
||||
<h1 class="crayons-title"><%= t("views.badges.heading") %></h1>
|
||||
<p><%= t("views.badges.desc") %></p>
|
||||
<div class="sticker-book crayons-card p-3 s:p-3 m:p-6 l:p-6 xl:p-8 grid gap-3 m:gap-4 l:gap-4 l:gap-6 grid-cols-2 s:grid-cols-2 m:grid-cols-3 l:grid-cols-4 xl:grid-cols-5 mb-6">
|
||||
<% @badges.each do |badge| %>
|
||||
<a href="/badge/<%= badge.slug %>">
|
||||
<img
|
||||
class="badge-image <%= "unearned" unless badge.id.in?(@earned_badge_achievements) %>"
|
||||
src="<%= optimized_image_url(badge.badge_image_url, width: 375) %>"
|
||||
alt="<%= badge.title %> badge"
|
||||
title="<%= badge.title %>"
|
||||
loading="lazy" />
|
||||
</a>
|
||||
<div
|
||||
role="button"
|
||||
onclick="window.Forem.showModal({prompt: true, contentSelector: '#badge-<%= badge.id %>', overlay: true})"
|
||||
style="width:auto; background-color: white;"
|
||||
class="crayons-card media-card media-card--all">
|
||||
<div style="background-color: #F5F5F5" class="p-3">
|
||||
<img
|
||||
style="width: 100%; aspect-ratio:1/1;"
|
||||
class="badge-image <%= "unearned" unless badge.id.in?(@earned_badge_achievements) %>"
|
||||
src="<%= optimized_image_url(badge.badge_image_url, width: 192) %>"
|
||||
alt="<%= badge.title %> badge"
|
||||
title="<%= badge.title %>"
|
||||
loading="lazy" />
|
||||
</div>
|
||||
<p aria-hidden="true" class="color-grey-800 align-center fw-bold fs-base flex lh-base justify-center p-3">
|
||||
<%= badge.title %>
|
||||
</p>
|
||||
|
||||
<div id="badge-<%= badge.id %>" class="hidden">
|
||||
<%= render partial: "badge_detail", locals: { badge: badge } %>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
|
|
|||
|
|
@ -1,14 +0,0 @@
|
|||
<% title t("views.badges.meta.name", title: @badge.title) %>
|
||||
|
||||
<div class="blank-space"></div>
|
||||
<div class="container article">
|
||||
<h1 style="text-align: center;font-size: min(2.7em, 7vw);max-width: 96%;margin: 30px auto;padding: 20px;"><%= t("views.badges.name", title: @badge.title) %></h1>
|
||||
<div class="body" style="text-align: center">
|
||||
<p>
|
||||
<img src="<%= optimized_image_url(@badge.badge_image_url, width: 375) %>" style="height: 250px" alt="<%= @badge.title %> badge">
|
||||
</p>
|
||||
<h4 style="max-width:550px;margin: 50px auto">
|
||||
<%= @badge.description %>
|
||||
</h4>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -6,7 +6,7 @@
|
|||
<div class="crayons-card__body">
|
||||
<div class="grid gap-4 grid-cols-3 s:grid-cols-4 m:grid-cols-2 align-center items-center js-profile-badges">
|
||||
<% achievements.each_with_index do |achievement, i| %>
|
||||
<a href="<%= badge_path(achievement.badge_slug) %>"
|
||||
<div role="button" onclick="window.Forem.showModal({prompt: true, contentSelector: '#badge-<%= achievement.badge_id %>', overlay: true})"
|
||||
title="<%= achievement.badge_title %>"
|
||||
class="js-profile-badge <% if i >= limit %>hidden<% end %>">
|
||||
<img src="<%= optimized_image_url(achievement.badge_image_url, width: 180) %>"
|
||||
|
|
@ -14,7 +14,12 @@
|
|||
class="mx-auto max-w-75 h-auto align-middle"
|
||||
style="transform: rotate(<%= rand(-10..10) %>deg);"
|
||||
loading="lazy" />
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div id="badge-<%= achievement.badge_id %>" class="hidden">
|
||||
<%= render partial: "badges/badge_detail", locals: { badge: achievement.badge } %>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -314,8 +314,6 @@ Rails.application.routes.draw do
|
|||
get "/t/:tag/admin", to: "tags#admin"
|
||||
patch "/tag/:id", to: "tags#update"
|
||||
|
||||
get "/badge/:slug", to: "badges#show", as: :badge
|
||||
|
||||
get "/top/:timeframe", to: "stories#index"
|
||||
|
||||
get "/:timeframe", to: "stories#index", constraints: { timeframe: /latest/ }
|
||||
|
|
|
|||
|
|
@ -31,35 +31,6 @@ RSpec.describe Badge, type: :model do
|
|||
end
|
||||
end
|
||||
|
||||
context "when callbacks are triggered after save" do
|
||||
let!(:badge) { create(:badge) }
|
||||
|
||||
describe "cache busting" do
|
||||
before do
|
||||
allow(EdgeCache::Bust).to receive(:new).and_return(cache_bust)
|
||||
allow(cache_bust).to receive(:call)
|
||||
end
|
||||
|
||||
it "calls the cache buster with the path" do
|
||||
badge.save
|
||||
|
||||
expect(cache_bust).to have_received(:call).with(badge.path)
|
||||
end
|
||||
|
||||
it "calls the cache buster with the internal path" do
|
||||
badge.save
|
||||
|
||||
expect(cache_bust).to have_received(:call).with("#{badge.path}?i=i")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "#path" do
|
||||
it "returns the path of the badge" do
|
||||
expect(badge.path).to eq("/badge/#{badge.slug}")
|
||||
end
|
||||
end
|
||||
|
||||
describe "#slug" do
|
||||
it "generates the correct slug for C" do
|
||||
badge = build(:badge, title: "C")
|
||||
|
|
|
|||
|
|
@ -28,21 +28,4 @@ RSpec.describe "Badges", type: :request do
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "GET /badge/:slug" do
|
||||
let(:badge) { create(:badge) }
|
||||
|
||||
context "when badge exists" do
|
||||
it "shows the badge" do
|
||||
get "/badge/#{badge.slug}"
|
||||
expect(response.body).to include CGI.escapeHTML(badge.title)
|
||||
end
|
||||
end
|
||||
|
||||
context "when badge does not exist" do
|
||||
it "renders 404" do
|
||||
expect { get "/badge/that-does-not-exists" }.to raise_error(ActiveRecord::RecordNotFound)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ RSpec.describe "Admin awards badges", type: :system do
|
|||
|
||||
visit "/#{user.username}/"
|
||||
|
||||
expect(page).to have_link(href: badge_path(Badge.last.slug))
|
||||
expect(page).to have_css("img[src='#{Badge.last.badge_image.url}']")
|
||||
end
|
||||
|
||||
it "does not award badges if no badge is selected", js: true do
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue