-
-
Notifications
You must be signed in to change notification settings - Fork 922
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Dashbaord "subject" layout with sidebar for current user.
- Loading branch information
1 parent
1510f96
commit be0a016
Showing
23 changed files
with
334 additions
and
284 deletions.
There are no files selected for viewing
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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" }) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 %> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 %> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.