Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update Speaker Show Page to match design on other pages #381

Merged
merged 13 commits into from
Dec 3, 2024
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions app/assets/images/icons/fontawesome/avocado-solid.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions app/assets/images/icons/fontawesome/browser-solid.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions app/assets/images/icons/fontawesome/pen-solid.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 2 additions & 1 deletion app/components/ui/button_component.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ class Ui::ButtonComponent < ApplicationComponent
warning: "btn-warning",
error: "btn-error",
ghost: "btn-ghost",
link: "btn-link"
link: "btn-link",
none: ""
}

SIZE_MAPPING = {
Expand Down
3 changes: 3 additions & 0 deletions app/controllers/speakers_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,10 @@ def index
# GET /speakers/1
def show
@talks = @speaker.talks.with_essential_card_data.order(date: :desc)
@topics = @speaker.topics.approved.tally.sort_by(&:last).reverse.map(&:first)

@back_path = speakers_path

set_meta_tags(@speaker)
end

Expand Down
3 changes: 3 additions & 0 deletions app/javascript/controllers/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ application.register("spotlight-search", SpotlightSearchController)
import TalksNavigationController from "./talks_navigation_controller"
application.register("talks-navigation", TalksNavigationController)

import ToggableController from "./toggable_controller"
application.register("toggable", ToggableController)

import TooltipController from "./tooltip_controller"
application.register("tooltip", TooltipController)

Expand Down
27 changes: 27 additions & 0 deletions app/javascript/controllers/toggable_controller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { Controller } from '@hotwired/stimulus'

export default class extends Controller {
static targets = ['toggable', 'toggle']

static values = {
hideText: {
type: String,
default: 'hide'
}
}

connect () {
this.toggleText = this.toggleTarget.textContent
}

toggle () {
this.toggleTarget.textContent = this.nextToggleText
this.toggableTargets.forEach(toggable => toggable.classList.toggle('hidden'))
}

get nextToggleText () {
return (this.toggleTarget.textContent === this.toggleText)
? this.hideTextValue
: this.toggleText
}
}
2 changes: 1 addition & 1 deletion app/jobs/speaker/enhance_profile_job.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ def perform(speaker:, sleep: 0)
website: speaker.website.presence || profile.blog || ""
)

speaker.broadcast_about
speaker.broadcast_header
sleep(sleep)
end

Expand Down
5 changes: 3 additions & 2 deletions app/models/speaker.rb
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ class Speaker < ApplicationRecord
has_many :talks, through: :speaker_talks, inverse_of: :speakers
has_many :events, -> { distinct }, through: :talks, inverse_of: :speakers
has_many :aliases, class_name: "Speaker", foreign_key: "canonical_id"
has_many :topics, through: :talks

belongs_to :canonical, class_name: "Speaker", optional: true
belongs_to :user, primary_key: :github_handle, foreign_key: :github, optional: true
Expand Down Expand Up @@ -159,8 +160,8 @@ def fetch_bsky_metadata!
Speaker::FetchBskyMetadata.new.perform(speaker: self)
end

def broadcast_about
broadcast_update_to self, target: dom_id(self, :about), partial: "speakers/about", locals: {speaker: self}
def broadcast_header
broadcast_update target: dom_id(self, :header_content), partial: "speakers/header_content", locals: {speaker: self}
end

def valid_website_url
Expand Down
2 changes: 1 addition & 1 deletion app/views/events/_header.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
</div>

<div class="flex flex-col gap-3 place-items-center">
<%= link_to "Visit Website", event.organisation.website, class: "btn btn-primary w-full", target: "_blank" %>
<%= link_to "Visit Website", event.website, class: "btn btn-neutral w-full", target: "_blank" %>
<%= link_to "View all #{event.organisation.name} events", event.organisation, class: "btn w-full" %>
</div>
</div>
Expand Down
4 changes: 1 addition & 3 deletions app/views/speakers/_actions.html.erb
Original file line number Diff line number Diff line change
@@ -1,3 +1 @@
<div class="flex flex-col gap-4 items-start">
<%= render "speakers/actions/#{user_kind}", speaker: speaker %>
</div>
<%= render "speakers/actions/#{user_kind}", speaker: speaker %>
13 changes: 13 additions & 0 deletions app/views/speakers/_header.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<div class="block lg:flex gap-8 align-center justify-between" id="<%= dom_id(speaker, :header) %>">
<%= render "speakers/header_content", speaker: speaker %>

<div class="flex flex-col gap-3 place-content-center align-center lg:max-w-[250px]">
<% if speaker.website.present? %>
<%= link_to speaker.website, class: "btn btn-sm btn-neutral w-full tooltip tooltip-bottom flex place-content-center", target: "_blank", data: {tip: speaker.website} do %>
<%= fa "arrow-up-right-from-square", size: :xs, class: "fill-white" %> Visit Website
<% end %>
<% end %>

<%= render "speakers/actions", speaker: speaker %>
</div>
</div>
36 changes: 36 additions & 0 deletions app/views/speakers/_header_content.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<div id="<%= dom_id(speaker, :header_content) %>" class="flex flex-col lg:flex-row gap-8 items-center lg:justify-right text-center lg:text-left mb-6 lg:mb-0">
<div class="relative w-fit">
<%= image_tag speaker.github_avatar_url(size: 200),
class: "rounded-full border border-[#D9DFE3] size-24 md:size-36",
height: 200,
width: 200,
alt: "GitHub picture profile of #{speaker.github}",
loading: :lazy %>

<% if speaker.verified? %>
<div class="absolute right-0 top-0 badge badge-accent flex gap-1">
<%= fa("badge-check", class: "fill-white", size: :xs) %>

Verified
</div>
<% end %>
</div>

<div class="flex-col flex gap-3 title justify-center">
<div class="flex flex-col lg:flex-row justify-center lg:justify-start text-black font-bold gap-2">
<h1 style="view-transition-name: title"><%= speaker.name %></h1>

<% if speaker.pronouns.present? && ["dont_specify", "not_specified"].exclude?(speaker.pronouns_type) %>
<span class="text-sm content-center text-[#737373]">(<%= speaker.pronouns %>)</span>
<% end %>
</div>

<p class="text-[#636B74] max-w-[700px]">
<%= speaker.bio %>
</p>

<div class="mt-2 flex justify-center lg:justify-start">
<%= render "speakers/socials", speaker: speaker %>
</div>
</div>
</div>
Original file line number Diff line number Diff line change
@@ -1,51 +1,39 @@
<div class="flex flex-col gap-3 pb-4" id="<%= dom_id(speaker, :about) %>">
<div id="socials" class="flex gap-3 my-3">
<div id="<%= dom_id(speaker, :socials) %>">
<div id="socials" class="flex gap-2">
<% if speaker.github.present? %>
<%= link_to "https://www.github.com/#{speaker.github}", target: "_blank", class: "hover:fill-gray-500" do %>
<%= link_to "https://www.github.com/#{speaker.github}", target: "_blank", class: "hover:bg-black hover:fill-white bg-white border rounded-full p-2 tooltip tooltip-top", data: {tip: speaker.github} do %>
<%= fab("github") %>
<% end %>
<% end %>

<% if speaker.twitter.present? %>
<%= link_to "https://www.x.com/#{speaker.twitter}", target: "_blank", class: "hover:fill-gray-500" do %>
<%= link_to "https://www.x.com/#{speaker.twitter}", target: "_blank", class: "hover:bg-[#74C0FC] hover:fill-white bg-white border rounded-full p-2 tooltip tooltip-top", data: {tip: speaker.twitter} do %>
<%= fab("twitter") %>
<% end %>
<% end %>

<% if speaker.bsky.present? %>
<%= link_to "https://bsky.app/profile/#{speaker.bsky}", target: "_blank", class: "hover:bg-[#0085FF] hover:fill-white bg-white border rounded-full p-2 tooltip tooltip-top", data: {tip: speaker.bsky} do %>
<%= fab("bluesky") %>
<% end %>
<% end %>

<% if speaker.mastodon.present? %>
<%= link_to speaker.mastodon, target: "_blank", class: "hover:fill-gray-500" do %>
<%= link_to speaker.mastodon, target: "_blank", class: "hover:bg-[#6364FF] hover:fill-white bg-white border rounded-full p-2 tooltip tooltip-top", data: {tip: speaker.mastodon} do %>
<%= fab("mastodon") %>
<% end %>
<% end %>

<% if speaker.linkedin.present? %>
<%= link_to "https://www.linkedin.com/in/#{speaker.linkedin}", target: "_blank", class: "hover:fill-gray-500" do %>
<%= link_to "https://www.linkedin.com/in/#{speaker.linkedin}", target: "_blank", class: "hover:bg-[#0A66C2] hover:fill-white bg-white border rounded-full p-2 tooltip tooltip-top", data: {tip: speaker.linkedin} do %>
<%= fab("linkedin") %>
<% end %>
<% end %>

<% if speaker.bsky.present? %>
<%= link_to "https://bsky.app/profile/#{speaker.bsky}", target: "_blank", class: "hover:fill-gray-500" do %>
<%= fab("bluesky") %>
<% end %>
<% end %>

<% if speaker.speakerdeck.present? %>
<%= link_to "https://speakerdeck.com/#{speaker.speakerdeck}", target: "_blank", class: "hover:fill-gray-500" do %>
<%= link_to "https://speakerdeck.com/#{speaker.speakerdeck}", target: "_blank", class: "hover:bg-[#009287] hover:fill-white bg-white border rounded-full p-2 tooltip tooltip-top", data: {tip: speaker.speakerdeck} do %>
<%= fab("speaker-deck") %>
<% end %>
<% end %>
</div>

<% if speaker.website.present? %>
<span>
<strong>Website:</strong> <%= link_to speaker.website, speaker.valid_website_url, target: "_blank" %>
</span>
<% end %>

<% if speaker.bio.present? %>
<span>
<strong>Bio:</strong> <%= speaker.bio %>
</span>
<% end %>
</div>
44 changes: 23 additions & 21 deletions app/views/speakers/actions/_admin.html.erb
Original file line number Diff line number Diff line change
@@ -1,26 +1,28 @@
<div class="flex flex-col items-center gap-4">
<%= ui_button url: edit_speaker_path(@speaker),
kind: :secondary,
data: {turbo_frame: "modal"},
outline: true,
size: :sm do %>
<%= heroicon :pencil_square %>
<span>Update speaker page</span>
<% end %>
<%= ui_button url: edit_speaker_path(@speaker),
kind: :none,
data: {turbo_frame: "modal"},
size: :sm,
class: "w-full" do %>
<%= fa :pen, size: :xs %>
<span>Update speaker page</span>
<% end %>

<% if speaker.github.present? || speaker.bsky.present? %>
<%= ui_button url: speakers_enhance_path(@speaker), method: :put, kind: :ghost, size: :sm do %>
<span>Enhance Profile</span>
<% end %>
<% if speaker.github.present? || speaker.bsky.present? %>
<%= ui_button url: speakers_enhance_path(@speaker), method: :put, kind: :none, size: :sm, class: "w-full", form_class: "w-full" do %>
<%= fab :github, size: :xs %>
<span>Fetch from GitHub</span>
<% end %>
<% end %>

<%= ui_button url: avo.resources_speaker_path(@speaker), target: :_blank, kind: :ghost, size: :sm do %>
<span>Open in Avo</span>
<% end %>
<%= ui_button url: avo.resources_speaker_path(@speaker), target: :_blank, kind: :none, size: :sm, class: "w-full" do %>
<%= fa :avocado, size: :xs %>

<span>Open in Avo</span>
<% end %>

<% if Rails.env.development? %>
<%= ui_button url: speaker_url(@speaker, host: "https://rubyvideo.dev", port: 443), target: :_blank, kind: :ghost, size: :sm do %>
<span>Show on RubyVideo.dev</span>
<% end %>
<% if Rails.env.development? %>
<%= ui_button url: speaker_url(@speaker, host: "https://rubyvideo.dev", port: 443), target: :_blank, kind: :none, size: :sm, class: "w-full" do %>
<%= fa :browser, size: :xs %>
<span>Show on RubyVideo.dev</span>
<% end %>
</div>
<% end %>
12 changes: 6 additions & 6 deletions app/views/speakers/actions/_anonymous.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@
Help us improve the speaker profile by adding a GitHub handle
<% end %>
<% else %>
<% if !speaker.verified? %>
<%= ui_button url: edit_speaker_path(speaker), kind: :secondary, outline: true, size: :sm, data: {turbo_frame: "modal"} do %>
<%= heroicon :pencil_square %>
<span>Suggest improvements</span>
<% end %>
<%= ui_button url: edit_speaker_path(speaker), kind: :none, size: :sm, data: {turbo_frame: "modal"} do %>
<%= fa :pen, size: :xs %>
<span>Suggest improvements</span>
<% end %>

<div class="content text-sm">
<% if !speaker.verified? %>
<div class="content text-sm mt-3">
<span>Are you <strong><%= speaker.name %></strong>?
<%= link_to sign_in_path, class: "link link-neutral font-light", data: {turbo_frame: "modal"} do %>
Claim your profile to manage and edit content.</span>
Expand Down
5 changes: 2 additions & 3 deletions app/views/speakers/actions/_owner.html.erb
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@

<%= ui_button url: edit_speaker_path(speaker), kind: :secondary, outline: true, size: :sm, data: {turbo_frame: "modal"} do %>
<%= heroicon :pencil_square %>
<%= ui_button url: edit_speaker_path(speaker), kind: :none, size: :sm, data: {turbo_frame: "modal"} do %>
<%= fa :pen, size: :xs %>
<span>Update my profile</span>
<% end %>
4 changes: 2 additions & 2 deletions app/views/speakers/actions/_signed_in.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
Help us improve the speaker profile by adding a GitHub handle
<% end %>
<% else %>
<%= ui_button url: edit_speaker_path(speaker), kind: :secondary, outline: true, size: :sm, data: {turbo_frame: "modal"} do %>
<%= heroicon :pencil_square %>
<%= ui_button url: edit_speaker_path(speaker), kind: :none, size: :sm, data: {turbo_frame: "modal"} do %>
<%= fa :pen, size: :xs %>
<span>Suggest improvements</span>
<% end %>
<% end %>
62 changes: 25 additions & 37 deletions app/views/speakers/show.html.erb
Original file line number Diff line number Diff line change
@@ -1,47 +1,35 @@
<%= turbo_refreshes_with method: :morph, scroll: :preserve %>
<%= turbo_stream_from @speaker %>

<div class="container py-8">
<div class="flex items-start flex-wrap sm:flex-nowrap gap-8 w-full">
<div class="w-full sm:w-1/3">
<div class="flex items-center gap-2 title text-primary">
<h1 style="view-transition-name: title"><%= @speaker.name %></h1>
<% if @speaker.pronouns.present? && ["dont_specify", "not_specified"].exclude?(@speaker.pronouns_type) %>
<span class="text-sm content-center text-[#737373]">(<%= @speaker.pronouns %>)</span>
<% end %>
</div>
<%= render partial: "speakers/header", locals: {speaker: @speaker} %>

<div class="relative w-fit">
<%= image_tag @speaker.avatar_url(size: 200),
class: "rounded-full mt-4",
height: 200,
width: 200,
alt: "GitHub picture profile of #{@speaker.github}",
loading: :lazy %>
<% if @topics.any? %>
<div class="mt-9 mb-3">
<%= render partial: "topics/badge_list", locals: {topics: @topics, back_to_url: request.fullpath, back_to_title: @speaker.name} %>
</div>
<% end %>

<% if @speaker.verified? %>
<div class="absolute right-0 top-0 badge badge-accent">Verified</div>
<% end %>
</div>
<hr class="my-6">

<%= render "speakers/about", speaker: @speaker %>
<%= render "speakers/actions", speaker: @speaker %>
</div>
<div role="tablist" class="tabs tabs-bordered mt-6">
<% if @speaker.talks.any? %>
<input type="radio" name="talk_tabs" role="tab" class="tab" aria-label="All Talks" style="width: 100px" checked>

<div class="w-full">
<div id="talks" class="min-w-full grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-8 h-full sm:p-4">
<%= render partial: "talks/card",
collection: @talks,
as: :talk,
locals: {
favoritable: true,
user_favorite_talks_ids: @user_favorite_talks_ids,
watched_talks_ids: user_watched_talks_ids,
back_to: request.fullpath,
back_to_title: @speaker.name
} %>
<div role="tabpanel" class="tab-content mt-6">
<div class="grid min-w-full grid-cols-1 gap-8 sm:grid-cols-2 md:grid-cols-3 md:[&>:nth-child(4)]:hidden lg:grid-cols-4 lg:[&>:nth-child(4)]:block">
<%= render partial: "talks/card",
collection: @talks,
as: :talk,
locals: {
favoritable: true,
user_favorite_talks_ids: @user_favorite_talks_ids,
watched_talks_ids: user_watched_talks_ids,
back_to: request.fullpath,
back_to_title: @speaker.name
} %>
</div>
</div>
</div>
<% end %>
</div>

<%= turbo_stream_from @speaker %>
</div>
Loading
Loading