Skip to content

Commit

Permalink
Dashbaord "subject" layout with sidebar for current user.
Browse files Browse the repository at this point in the history
  • Loading branch information
martinemde committed Oct 30, 2024
1 parent 1510f96 commit be0a016
Show file tree
Hide file tree
Showing 23 changed files with 334 additions and 284 deletions.
150 changes: 35 additions & 115 deletions app/assets/images/icons.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
11 changes: 11 additions & 0 deletions app/assets/stylesheets/hammy.css
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,14 @@
dialog:modal {
max-width: 100vw;
}

/* Hide scrollbar for Chrome, Safari and Opera */
.no-scrollbar::-webkit-scrollbar {
display: none;
}

/* Hide scrollbar for IE, Edge and Firefox */
.no-scrollbar {
-ms-overflow-style: none; /* IE and Edge */
scrollbar-width: none; /* Firefox */
}
3 changes: 1 addition & 2 deletions app/controllers/dashboards_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,13 @@ class DashboardsController < ApplicationController
before_action :redirect_to_new_mfa, if: :mfa_required_not_yet_enabled?
before_action :redirect_to_settings_strong_mfa_required, if: :mfa_required_weak_level_enabled?

layout "hammy"
layout "subject"

def show
add_breadcrumb t("breadcrumbs.dashboard")

respond_to do |format|
format.html do
@user = current_user
find_my_gems
find_subscribed_gems
find_latest_updates
Expand Down
2 changes: 1 addition & 1 deletion app/controllers/subscriptions_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ class SubscriptionsController < ApplicationController

before_action :find_rubygem, only: %i[create destroy]

layout "hammy"
layout "subject"

def index
add_breadcrumb t("breadcrumbs.dashboard"), dashboard_path
Expand Down
15 changes: 15 additions & 0 deletions app/javascript/controllers/scroll_controller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/* A controller that, when loaded, causes the page to refresh periodically */

import { Controller } from "@hotwired/stimulus"

export default class extends Controller {
static targets = ["scroll", "scrollLeft"]

scrollLeftTargetConnected() {
this.element.scrollLeft = this.scrollLeftTarget.offsetLeft + this.scrollLeftTarget.offsetWidth / 2 - this.element.offsetWidth / 2
}

scrollTargetConnected() {
this.scrollTarget.scrollIntoView({ behavior: "smooth" })
}
}
2 changes: 1 addition & 1 deletion app/views/components/card_component.rb
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ def list_item_to(url = nil, **options, &)
li do
link_to(url, **options) do
span(class: "flex-1", &)
render_icon("chevron-forward", class: "w-8 h-8 ml-2 text-neutral-800 dark:text-white fill-current")
render_icon("arrow-forward-ios", class: "w-8 h-8 ml-2 -mr-2 text-neutral-800 dark:text-white fill-current")
end
end
end
Expand Down
36 changes: 36 additions & 0 deletions app/views/components/subject/nav_component.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# frozen_string_literal: true

class Subject::NavComponent < ApplicationComponent
include Phlex::Rails::Helpers::LinkTo

attr_reader :current

def initialize(current: :dashboard)
@current = current
end

def view_template(&)
div(class: "relative -mx-8 lg:mx-0") do
nav(data: { controller: "scroll" }, class: NAV, &)
div class: "#{GRADIENT} w-12 right-0 bg-gradient-to-l" # Gradient fade right
div class: "#{GRADIENT} w-8 left-0 bg-gradient-to-r" # Gradient fade left
end
end

NAV = "relative flex overflow-x-auto no-scrollbar whitespace-nowrap py-4 space-x-2 pl-8 pr-12 " \
"lg:flex-col lg:px-0 lg:space-x-0 lg:space-y-2"
GRADIENT = "lg:hidden absolute top-0 h-full pointer-events-none from-white dark:from-black"
LINK = "flex items-center space-x-2 h-12 lg:h-14 px-3 py-1 lg:px-6 lg:py-2 rounded"
ACTIVE_LINK = "#{LINK} bg-orange-100 dark:bg-orange-900 text-neutral-900 dark:text-white"
INACTIVE_LINK = "#{LINK} bg-neutral-050 text-neutral-600 hover:bg-neutral-200 " \
"dark:bg-neutral-950 dark:text-neutral-400 dark:hover:bg-neutral-800"

def link(text, url, icon:, name: nil, **options)
is_current = name == current
data = { scroll_target: "scrollLeft" } if is_current
link_to(url, data:, class: is_current ? ACTIVE_LINK : INACTIVE_LINK) do
unsafe_raw helpers.icon_tag(icon, size: 7, class: is_current && "text-orange-500")
span { text }
end
end
end
42 changes: 42 additions & 0 deletions app/views/dashboards/_subject.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<%
user ||= @user || current_user
current ||= :dashboard
%>

<div class="flex flex-wrap lg:flex-col items-start mb-6 lg:mb-10">
<%= avatar 328, "user_gravatar", theme: :dark, class: "h-24 w-24 lg:h-40 lg:w-40 rounded-lg object-cover mr-4" %>

<div class="lg:w-full lg:mt-2">
<h2 class="font-bold text-h4"><%= user.display_handle %></h2>
<% if user.full_name.present? %>
<p class="text-neutral-500 text-b3"><%= user.full_name %></p>
<% end %>
</div>
</div>

<% if user.public_email? || user == current_user %>
<div class="flex items-center mb-4 text-b3 lg:text-b2">
<%= icon_tag("mail", color: :primary, class: "h-6 w-6 text-orange mr-3") %>
<p class="text-neutral-800 dark:text-white"><%=
mail_to(user.email, encode: "hex")
%></p>
</div>
<% end %>
<% if user.twitter_username.present? %>
<div class="flex items-center mb-4 text-b3 lg:text-b2">
<%= icon_tag("x-twitter", color: :primary, class: "w-6 text-orange mr-3") %>
<p class="text-neutral-800 dark:text-white"><%=
link_to(
twitter_username(user),
twitter_url(user)
)
%></p>
</div>
<% end %>
<%= render Subject::NavComponent.new(current:) do |nav| %>
<%= nav.link t("layouts.application.header.dashboard"), dashboard_path, name: :dashboard, icon: "space-dashboard" %>
<%= nav.link t("dashboards.show.my_subscriptions"), subscriptions_path, name: :subscriptions, icon: "notifications" %>
<%= nav.link t("layouts.application.header.settings"), edit_settings_path, name: :settings, icon: "settings" %>
<% end %>
218 changes: 90 additions & 128 deletions app/views/dashboards/show.html.erb
Original file line number Diff line number Diff line change
@@ -1,149 +1,111 @@
<% @title = t('.title') %>
<!-- Subscriptions -->
<% content_for :subject do %>
<% render "dashboards/subject", user: current_user %>
<% end %>

<div class="flex flex-wrap space-y-4 lg:space-y-0 lg:space-x-20">
<aside class="w-full lg:w-96 lg:mb-32">
<%= render CardComponent.new do |c| %>
<!-- Profile Header -->
<div class="flex flex-wrap items-center mb-4">
<!-- Profile Picture -->
<%# <img src="https://via.placeholder.com/100" alt="Profile Picture" class="w-24 h-24 rounded-lg object-cover mr-4"> %>
<%= avatar 328, "user_gravatar", theme: :dark, class: "h-24 w-24 lg:h-40 lg:w-40 rounded-lg object-cover mr-4" %>
<!-- Main Content -->
<h1 class="text-h2 mb-10"><%= t(".title") %></h1>

<!-- Name and Title -->
<div class="lg:w-full lg:mt-2">
<h2 class="text-lg font-bold"><%= @user.display_handle %></h2>
<% if @user.full_name.present? %>
<p class="text-neutral-500"><%= @user.full_name %></p>
<% end %>
</div>
</div>

<!-- Contact Info -->
<div class="my-6">
<% if @user.public_email? || @user == current_user %>
<div class="flex items-center mb-2">
<%= icon_tag("mail", color: :primary, class: "h-6 w-6 text-orange mr-3") %>
<p class="text-neutral-800 dark:text-white"><%=
mail_to(
@user.email,
encode: "hex",
class: "profile__header__attribute t-link--black"
)
%></p>
</div>
<% end %>
<% if @user.twitter_username.present? %>
<div class="flex items-center mb-2">
<%= icon_tag("x-twitter", color: :primary, class: "w-6 text-orange mr-3") %>
<p class="text-neutral-800 dark:text-white"><%=
link_to(
twitter_username(@user),
twitter_url(@user)
)
%></p>
</div>
<% end %>
</div>

<% if @user.memberships.any? %>
<!-- Organizations -->
<div class="max-w-96 mb-2 space-y-2">
<h3 class="text-neutral-800 dark:text-white font-semibold text-b3 uppercase mb-2">Organizations</h3>
<% @user.memberships.preload(:organization).each do |membership| %>
<div class="flex justify-between">
<p class="text-neutral-800 dark:text-white"><%= membership.organization.name %></p>
<p class="text-neutral-500 capitalize"><%= membership.role %></p>
</div>
<% end %>
</div>
<%= render CardComponent.new do |c| %>
<%= c.head(divide: true) do %>
<%= c.title t(".latest"), icon: :history %>
<div class="flex space-x-2 items-center">
<%= link_to dashboard_path(api_key: current_user.api_key, format: :atom), id: 'feed', title: t('.latest_title'), class: 'items-center' do %>
<%= icon_tag("rss-feed", size: 6, class: "w-6 h-6 fill-orange") %>
<% end %>
<% end %>
</aside>
</div>
<% end %>
<div class="flex-1">
<%= render CardComponent.new do |c| %>
<%= c.head(divide: true) do %>
<%= c.title t(".latest"), icon: :history %>
<div class="flex space-x-2 items-center">
<%= link_to dashboard_path(api_key: current_user.api_key, format: :atom), id: 'feed', title: t('.latest_title'), class: 'items-center' do %>
<%= icon_tag("rss-feed", size: 6, class: "w-6 h-6 fill-orange") %>
<% if @latest_updates.empty? %>
<%= prose do %>
<i><%= t('.no_subscriptions_html', :gem_link => link_to(t('.gem_link_text'), rubygem_path("rake"))) %></i>
<% end %>
<% else %>
<%= c.scrollable do %>
<%= render Card::TimelineComponent.new do |t| %>
<% @latest_updates.each do |version| %>
<%
pusher_link = if version.pusher.present?
link_to_user(version.pusher)
elsif version.pusher_api_key&.owner.present?
link_to_pusher(version.pusher_api_key.owner)
end
%>
<%= t.timeline_item(version.authored_at, pusher_link) do %>
<div class="flex text-b1 text-neutral-800 dark:text-white"><%= link_to version.rubygem.name, rubygem_path(version.rubygem.slug) %></div>
<%= version_number(version) %>
<% end %>
</div>
<% end %>
<% end %>
<% end %>
<% end %>
<% end %>
<% if @latest_updates.empty? %>
<%= prose do %>
<i><%= t('.no_subscriptions_html', :gem_link => link_to(t('.gem_link_text'), rubygem_path("rake"))) %></i>
<% end %>
<% else %>
<%= c.scrollable do %>
<%= render Card::TimelineComponent.new do |t| %>
<% @latest_updates.each do |version| %>
<%
pusher_link = if version.pusher.present?
link_to_user(version.pusher)
elsif version.pusher_api_key&.owner.present?
link_to_pusher(version.pusher_api_key.owner)
end
%>
<%= t.timeline_item(version.authored_at, pusher_link) do %>
<div class="flex text-b1 text-neutral-800 dark:text-white"><%= link_to version.rubygem.name, rubygem_path(version.rubygem.slug) %></div>
<%= version_number(version) %>
<% end %>
<% end %>
<% end %>
<%= render CardComponent.new do |c| %>
<%= c.head do %>
<%= c.title t(".mine"), icon: "gems", count: @my_gems_count %>
<% end %>
<% if @my_gems.empty? %>
<%= prose do %>
<i><%= t('.no_owned_html', :creating_link => link_to(t('.creating_link_text'), "https://guides.rubygems.org/make-your-own-gem/")) %></i>
<% end %>
<% else %>
<%= c.divided_list do %>
<% @my_gems.each do |rubygem| %>
<%= c.list_item_to(
rubygem_path(rubygem.slug),
title: short_info(rubygem.most_recent_version),
) do %>
<div class="flex flex-col w-full justify-between">
<div class="flex flex-row w-full items-center justify-between">
<h4 class="text-b1 flex"><%= rubygem.name %></h4>
<%= version_number(rubygem.most_recent_version) %>
</div>
<div class="flex flex-row w-full items-center justify-between">
<%= download_count_component(rubygem, class: "flex") %>
<div class="flex text-neutral-600"><%= version_date_component(rubygem.most_recent_version) %></div>
</div>
</div>
<% end %>
<% end %>
<% end %>
<% end %>
<% end %>
<%= render CardComponent.new do |c| %>
<%= c.head do %>
<%= c.title t(".mine"), icon: :gems, count: @my_gems_count %>
<% end %>
<% if @my_gems.empty? %>
<%= prose do %>
<i><%= t('.no_owned_html', :creating_link => link_to(t('.creating_link_text'), "https://guides.rubygems.org/make-your-own-gem/")) %></i>
<% end %>
<% else %>
<%= c.divided_list do %>
<% @my_gems.each do |rubygem| %>
<%= c.list_item_to(
rubygem_path(rubygem.slug),
title: short_info(rubygem.most_recent_version),
) do %>
<div class="flex flex-col w-full justify-between">
<div class="flex flex-row w-full items-center justify-between">
<h4 class="text-b1 flex"><%= rubygem.name %></h4>
<%= version_number(rubygem.most_recent_version) %>
</div>
<div class="flex flex-row w-full items-center justify-between">
<%= download_count_component(rubygem, class: "flex") %>
<div class="flex text-neutral-600"><%= version_date_component(rubygem.most_recent_version) %></div>
</div>
</div>
<% end %>
<% end %>
<% if @subscribed_gems.present? %>
<%= render CardComponent.new do |c| %>
<%= c.head do %>
<%= c.title t(".my_subscriptions"), icon: "notifications", count: @subscribed_gems_count %>
<%= link_to t("view_all"), subscriptions_path, class: "text-sm text-orange-500" %>
<% end %>
<%= c.list do %>
<% @subscribed_gems.each do |gem| %>
<%= c.list_item_to(rubygem_path(gem.slug), title: short_info(gem.most_recent_version)) do %>
<h3 class="text-b1"><%= gem.name %></h3>
<p class="text-b3 text-neutral-600"><%= short_info(gem.most_recent_version) %></p>
<% end %>
<% end %>
<% end %>
<% end %>
<% end %>
<% if @subscribed_gems.present? %>
<%= render CardComponent.new do |c| %>
<%= c.head do %>
<%= c.title t(".my_subscriptions"), icon: :gems, count: @subscribed_gems_count %>
<%= link_to t("view_all"), subscriptions_path, class: "text-sm text-orange-500" %>
<% end %>
<%= c.with_list(@subscribed_gems) do |gem| %>
<div class="flex flex-row w-full items-center justify-between">
<%= link_to rubygem_path(gem.slug), title: short_info(gem.most_recent_version) do %>
<h3 class="text-b1"><%= gem.name %></h3>
<p class="text-b3 text-neutral-600"><%= short_info(gem.most_recent_version) %></p>
<% end %>
<% if current_user.memberships.any? %>
<!-- Organizations -->
<%= render CardComponent.new do |c| %>
<%= c.head do %>
<%= c.title t(".organizations"), icon: "organizations", count: current_user.memberships.count %>
<%= link_to t("view_all"), "#", class: "text-sm text-orange-500" %>
<% end %>
<%= c.divided_list do %>
<% current_user.memberships.preload(:organization).each do |membership| %>
<%= c.list_item_to("#") do %>
<div class="flex justify-between">
<p class="text-neutral-800 dark:text-white"><%= membership.organization.name %></p>
<p class="text-neutral-500 capitalize"><%= membership.role %></p>
</div>
<% end %>
<% end %>
<% end %>
</div>
</div>
<% end %>
<% end %>
4 changes: 2 additions & 2 deletions app/views/layouts/_breadcrumbs.html.erb
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<div class="clear-both w-full bg-neutral-050 dark:bg-neutral-950 px-8 py-1 text-neutral-800 dark:text-white">
<div class="hidden lg:block w-full px-8 py-1 lg:pb-8 bg-neutral-050 dark:bg-neutral-950 text-neutral-800 dark:text-white">
<div class="max-w-screen-xl mx-auto flex items-center">
<nav class="flex justify-start items-center text-b2" aria-label="Breadcrumb">
<!-- Home breadcrumb -->
Expand All @@ -7,7 +7,7 @@
<% end %>
<% breadcrumbs.each do |name, link| %>
<%= icon_tag "chevron-right", size: 6, class: "text-neutral-600 dark:text-neutral-700 fill-neutral-600 dark:fill-neutral-700", size: 6, aria: { hidden: "true" } %>
<%= icon_tag "chevron-right", size: 6, class: "text-neutral-600 dark:text-neutral-700 fill-neutral-600 dark:fill-neutral-700", aria: { hidden: "true" } %>
<% if link %>
<%= link_to name, link, class: "inline-block p-1 hover:text-neutral-600 dark:hover:text-neutral-400" %>
<% else %>
Expand Down
Loading

0 comments on commit be0a016

Please sign in to comment.