[deploy] Dashboard updates (#8879)

* flare tag line height

* .

* .

* .

* .

* specs

* spec

* .

* init

* .

* .

* js refactor

* js

* update spec

* Fix infinite scroll

* typo

* move IF

* pro analytics link fix

* Clean up tests

* Refactor adding of html

Co-authored-by: benhalpern <bendhalpern@gmail.com>
This commit is contained in:
ludwiczakpawel 2020-06-25 19:10:17 +02:00 committed by GitHub
parent d7d0c49169
commit c9c88c7cc1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
23 changed files with 579 additions and 387 deletions

View file

@ -0,0 +1 @@
<svg width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M10.667 8v1.333H7.333v7.334h7.334v-3.334H16v4a.666.666 0 01-.667.667H6.667A.666.666 0 016 17.333V8.667A.667.667 0 016.667 8h4zM18 6v5.333h-1.333V8.275l-5.196 5.196-.942-.942 5.194-5.196h-3.056V6H18z" /></svg>

After

Width:  |  Height:  |  Size: 301 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

View file

@ -1,3 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="95" height="95" viewBox="0 0 95 95">
<path d="M23 35H2a2 2 0 00-2 2v21a2 2 0 002 2h21a2 2 0 002-2V37a2 2 0 00-2-2zm35 0H37a2 2 0 00-2 2v21a2 2 0 002 2h21a2 2 0 002-2V37a2 2 0 00-2-2zm35 0H72a2 2 0 00-2 2v21a2 2 0 002 2h21a2 2 0 002-2V37a2 2 0 00-2-2z"/>
</svg>

Before

Width:  |  Height:  |  Size: 312 B

View file

@ -53,15 +53,8 @@ function insertNext(params, buildCallback) {
}
});
var distanceFromBottom =
document.documentElement.scrollHeight - document.body.scrollTop;
var newNode = document.createElement('div');
newNode.innerHTML = newFollowersHTML;
var singleArticles = document.querySelectorAll(
'.single-article, .crayons-story',
);
var lastElement = singleArticles[singleArticles.length - 1];
insertAfter(newNode, lastElement);
var followList = document.getElementById('following-wrapper');
followList.insertAdjacentHTML('beforeend', newFollowersHTML);
if (nextPage > 0) {
fetching = false;
}
@ -70,71 +63,80 @@ function insertNext(params, buildCallback) {
function buildFollowsHTML(follows) {
return (
'<div id="follows-' +
'<div class="crayons-card p-4 m:p-6 flex s:grid single-article" id="follows-' +
follows.id +
'" class="single-article">\n' +
' <a href="' +
'">' +
'<a href="' +
follows.path +
'" class="block-link">\n' +
' <h2>\n' +
' <img alt="' +
'" class="crayons-avatar crayons-avatar--2xl s:mb-2 s:mx-auto">' +
'<img alt="@' +
follows.username +
' profile image" src="' +
' profile image" class="crayons-avatar__image" src="' +
follows.profile_image +
'" />\n' +
' ' +
'" />' +
'</a>' +
'<div class="pl-4 s:pl-0 self-center">' +
'<h3 class="s:mb-1 p-0">' +
'<a href="' +
follows.path +
'">' +
follows.name +
'\n' +
' <span class="dashboard-username">@' +
'</a>' +
'</h3>' +
'<p class="s:mb-4">' +
'<a href="' +
follows.path +
'" class="crayons-link crayons-link--secondary">' +
'@' +
follows.username +
'</span>\n' +
' </h2>\n' +
' </a>\n' +
'</a>' +
'</p>' +
'</div>' +
'</div>'
);
}
var negativeFollow = -1;
function buildTagsHTML(tag) {
var tagHTML = '';
if (tag.points < 0 && negativeFollow === -1) {
tagHTML += '<h2>Negative Tags (anti-follows)</h2>';
negativeFollow = 0;
var antifollow = '';
if (tag.points < 0) {
antifollow =
'<span class="crayons-indicator crayons-indicator--critical crayons-indicator--outlined" title="This tag has negative follow weight">Anti-follow</span>';
}
return (
tagHTML +
'<div id="follows-' +
'<div class="crayons-card p-4 m:p-6 flex flex-col single-article" id="follows-' +
tag.id +
'" class="single-article" style="border: 1px solid ' +
'" style="border: 1px solid ' +
tag.color +
';box-shadow: 3px 3px 0px ' +
'; box-shadow: 3px 3px 0' +
tag.color +
'">\n' +
' <h2>\n' +
' <a href="/t/' +
'">' +
'<h3 class="s:mb-1 p-0 fw-medium">' +
'<a href="/t/' +
tag.name +
'">\n' +
' ' +
'" class="crayons-tag crayons-tag--l">' +
'<span class="crayons-tag__prefix">#</span>' +
tag.name +
'\n' +
' </a>\n' +
' <form class="edit_follow" id="edit_follow_' +
'</a>' +
antifollow +
'</h3>' +
'<p class="grid-cell__summary"></p>' +
'<form class="edit_follow flex items-center flex-nowrap mb-4" id="edit_follow_' +
tag.id +
'" action="/follows/' +
tag.id +
'" accept-charset="UTF-8" method="post">\n' +
' <input name="utf8" type="hidden" value="✓">\n' +
' <input type="hidden" name="_method" value="patch">\n' +
' <input type="hidden" name="authenticity_token" value="' +
'" accept-charset="UTF-8" method="post">' +
'<input name="utf8" type="hidden" value="✓">' +
'<input type="hidden" name="_method" value="patch">' +
'<input type="hidden" name="authenticity_token" value="' +
tag.token +
'">\n' +
' <label for="follow_points">Follow Weight:</label>\n' +
' <input step="any" required="required" type="number" value="' +
'">' +
'<label for="follow_points" class="fs-s flex-1 pr-2 color-base-60 align-right whitespace-nowrap">Follow weight:</label>' +
'<input step="any" class="crayons-textfield flex-1 fs-s" required="required" type="number" style="max-width:90px" value="' +
tag.points +
'" name="follow[points]" id="follow_points">\n' +
' <input type="submit" name="commit" value="Submit">\n' +
' </form>\n' +
' </h2>\n' +
'" name="follow[points]" id="follow_points">' +
'<button type="submit" class="crayons-btn crayons-btn--ghost crayons-btn--s" name="commit">Save</button>' +
'</form>' +
'</div>'
);
}

View file

@ -1,11 +1,25 @@
/* global InstantClick */
'use strict';
function initializeDashboardSort() {
const dashboardSorter = document.getElementById('dashboard_sort');
function selectNavigation(select, urlPrefix) {
const trigger = document.getElementById(select);
if (dashboardSorter) {
dashboardSorter.addEventListener('change', (event) => {
window.location.assign(`/dashboard?sort=${event.target.value}`);
if (trigger) {
trigger.addEventListener('change', (event) => {
let url = event.target.value;
if (urlPrefix) {
url = urlPrefix + url;
}
InstantClick.preload(url);
InstantClick.display(url);
});
}
}
function initializeDashboardSort() {
selectNavigation('dashboard_sort', '/dashboard?sort=');
selectNavigation('dashboard_author');
selectNavigation('mobile_nav_dashboard');
}

View file

@ -13,7 +13,8 @@
-webkit-border-horizontal-spacing: 0;
-webkit-border-vertical-spacing: 0;
td, th {
td,
th {
padding: var(--su-2);
@media (min-width: $breakpoint-m) {
@ -27,6 +28,11 @@
td {
transition: background var(--transition-props);
border-bottom: 1px solid var(--body-bg);
}
thead {
border-radius: var(--radius) var(--radius) 0 0;
}
th {
@ -34,6 +40,14 @@
font-weight: var(--fw-medium);
text-transform: uppercase;
color: var(--base-60);
&:first-child {
border-radius: var(--radius) 0 0 0;
}
&:last-child {
border-radius: 0 var(--radius) 0 0;
}
}
tbody {
@ -49,6 +63,10 @@
}
&:last-child {
td {
border-bottom: none;
}
td:first-child {
border-radius: 0 0 0 var(--radius);
}
@ -74,11 +92,5 @@
}
}
}
tr:not(:last-child) {
td {
border-bottom: 1px solid var(--body-bg);
}
}
}
}

View file

@ -21,4 +21,8 @@
&[href]:hover {
color: var(--tag-color-hover);
}
&--l {
font-size: var(--fs-l);
}
}

View file

@ -27,3 +27,4 @@
@import 'views/article';
@import 'views/article-form';
@import 'views/dashboard';

View file

@ -0,0 +1,48 @@
@import '../config/import';
.dashboard-story {
padding: var(--su-4);
align-items: center;
display: grid;
grid-gap: var(--su-1);
grid-template-rows: auto auto;
@media (min-width: $breakpoint-m) {
grid-template-columns: 4fr 2fr 2fr;
grid-template-rows: auto;
grid-gap: var(--su-2);
}
& + & {
border-top: 1px solid var(--base-10);
}
&:hover {
background: var(--base-0);
}
&__title {
grid-column-end: span 2;
@media (min-width: $breakpoint-m) {
grid-column-end: unset;
}
}
&__actions {
justify-self: end;
display: flex;
}
}
.grid-cell {
&__summary {
color: var(--base-60);
overflow: hidden;
line-height: var(--lh-tight);
display: -webkit-box;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
margin-bottom: var(--su-4);
}
}

View file

@ -1,19 +1,54 @@
<div class="actions">
<a class="action <%= "active" if params[:action] == "show" && (params[:which] == "organization" || params[:which].blank?) %>" href="/dashboard">
<span>POSTS</span>
<span>(<%= @user.articles_count %>)</span>
<nav class="hidden m:block">
<a class="crayons-link crayons-link--block <%= "crayons-link--current" if params[:action] == "show" && (params[:which] == "organization" || params[:which].blank?) %>" href="/dashboard">
Posts
<span class="crayons-indicator"><%= @user.articles_count %></span>
</a>
<a class="action <%= "active" if params[:action] == "followers" %>" href="/dashboard/user_followers">
<span>FOLLOWERS</span>
<span>(<%= @user.followers_count %>)</span>
<a class="crayons-link crayons-link--block <%= "crayons-link--current" if params[:action] == "followers" %>" href="/dashboard/user_followers">
Followers
<span class="crayons-indicator"><%= @user.followers_count %></span>
</a>
<a class="action <%= "active" if params[:action] == "following" || params[:action].include?("following") %>" href="/dashboard/following">
<span>FOLLOWING</span>
<span>(<%= @user.following_users_count + @user.following_tags_count + @user.following_organizations_count + @user.following_podcasts_count %>)</span>
<a class="crayons-link crayons-link--block <%= "crayons-link--current" if params[:action] == "following_tags" %>" href="/dashboard/following_tags">
Following tags
<span class="crayons-indicator"><%= @user.following_tags_count %></span>
</a>
<a class="crayons-link crayons-link--block <%= "crayons-link--current" if params[:action] == "following_users" %>" href="/dashboard/following_users">
Following users
<span class="crayons-indicator"><%= @user.following_users_count %></span>
</a>
<a class="crayons-link crayons-link--block <%= "crayons-link--current" if params[:action] == "following_organizations" %>" href="/dashboard/following_organizations">
Following organizations
<span class="crayons-indicator"><%= @user.following_organizations_count %></span>
</a>
<a class="crayons-link crayons-link--block <%= "crayons-link--current" if params[:action] == "following_podcasts" %>" href="/dashboard/following_podcasts">
Following podcasts
<span class="crayons-indicator"><%= @user.following_podcasts_count %></span>
</a>
<a class="crayons-link crayons-link--block" href="/listings/dashboard" data-no-instant>
Listings
<%= inline_svg_tag("external-link.svg", aria: true, class: "crayons-icon", title: "Moderation") %>
</a>
<% if @user.has_role? :pro %>
<a class="action" href="/dashboard/pro">
<span>PRO ANALYTICS</span>
<a class="crayons-link crayons-link--block" href="/dashboard/pro">
Pro Analytics
</a>
<% end %>
</div>
<% if @organizations && (params[:which].blank? || params[:which] == "organization") %>
<% @organizations.each do |org| %>
<a class="crayons-link crayons-link--block" href="/dashboard/pro/org/<%= org.id %>">Pro Analytics for <%= org.name %></a>
<% end %>
<% end %>
<% if current_user.created_at < 2.weeks.ago %>
<a class="crayons-btn crayons-btn--secondary w-100 mt-4" href="/videos/new" data-no-instant>
Upload a video
</a>
<% end %>
</nav>

View file

@ -0,0 +1,25 @@
<div class="block m:hidden px-2">
<select id="mobile_nav_dashboard" class="crayons-select">
<option value="/dashboard" <%= "selected" if params[:action] == "show" && (params[:which] == "organization" || params[:which].blank?) %>>Posts (<%= @user.articles_count %>)</option>
<option value="/dashboard/user_followers" <%= "selected" if params[:action] == "followers" %>>Followers (<%= @user.followers_count %>)</option>
<option value="/dashboard/following_tags" <%= "selected" if params[:action] == "following_tags" %>>Following tags (<%= @user.following_tags_count %>)</option>
<option value="/dashboard/following_users" <%= "selected" if params[:action] == "following_users" %>>Following users (<%= @user.following_users_count %>)</option>
<option value="/dashboard/following_organizations" <%= "selected" if params[:action] == "following_organizations" %>>Following organizations (<%= @user.following_organizations_count %>)</option>
<option value="/dashboard/following_podcasts" <%= "selected" if params[:action] == "following_podcasts" %>>Following podcasts (<%= @user.following_podcasts_count %>)</option>
<option value="/listings/dashboard">Listings</option>
<% if @user.has_role? :pro %>
<option value="/dashboard/pro">Pro Analytics</option>
<% end %>
<% if @organizations && (params[:which].blank? || params[:which] == "organization") %>
<% @organizations.each do |org| %>
<option value="/dashboard/pro/org/<%= org.id %>">Pro Analytics for <%= org.name %></option>
<% end %>
<% end %>
<% if current_user.created_at < 2.weeks.ago %>
<option value="/videos/new">Upload a video</option>
<% end %>
</select>
</div>

View file

@ -1,20 +1,23 @@
<% num_views = @page_views_count %>
<div class="dashboard-analytics-header-wrapper">
<div class="dashboard-analytics-header">
<span><%= number_with_delimiter(@reactions_count, delimeter: ",") %></span>
<div class="dashboard-analytics-sub-indicator">
<img src="<%= asset_path "emoji/emoji-one-heart.png" %>" alt="heart" />
<img src="<%= asset_path "emoji/emoji-one-unicorn.png" %>" alt="unicorn" />
<img src="<%= asset_path "emoji/emoji-one-bookmark.png" %>" alt="bookmark" />
Total Post Reactions
</div>
<div class="grid grid-cols-2 m:grid-cols-4 gap-2 m:gap-4 p-2 m:p-0">
<div class="crayons-card crayons-card--secondary p-3 m:p-6">
<strong class="fs-2xl m:fs-3xl lh-tight color-base-90"><%= number_with_delimiter(@reactions_count, delimeter: ",") %></strong>
<span class="color-base-60 block">Total post reactions</span>
</div>
<div class="dashboard-analytics-header" id="dashboard-analytics-header">
<span><%= num_views > 500 ? number_with_delimiter(num_views, delimeter: ",") : "under 500" %></span>
<div class="dashboard-analytics-sub-indicator">
<img id="dashboard-analytics-image" src="<%= asset_path "emoji/apple-eyes.png" %>" alt="eyes" />
Total Post Views
</div>
<div class="crayons-card crayons-card--secondary p-3 m:p-6">
<strong class="fs-2xl m:fs-3xl lh-tight color-base-90"><%= num_views > 500 ? number_with_delimiter(num_views, delimeter: ",") : "< 500" %></strong>
<span class="color-base-60 block">Total post views</span>
</div>
<div class="crayons-card crayons-card--secondary p-3 m:p-6">
<strong class="fs-2xl m:fs-3xl lh-tight color-base-90"><%= @user.listings.count %></strong>
<span class="color-base-60 block">Listings created</span>
</div>
<div class="crayons-card crayons-card--secondary p-3 m:p-6">
<strong class="fs-2xl m:fs-3xl lh-tight color-base-90"><%= @user.credits.count %></strong>
<span class="color-base-60 block">Credits available</span>
</div>
</div>

View file

@ -1,23 +1,18 @@
<tr class="js-dashboard-story spec__dashboard-story <%= "story-unpublished" unless article.published %> <%= "js-dashboard-story story-archived hidden" if article.archived %>">
<td>
<h3 class="fs-l">
<a href="<%= article.current_state_path %>" class="flex items-center">
<div class="dashboard-story js-dashboard-story spec__dashboard-story single-article <%= "story-unpublished" unless article.published %> <%= "js-dashboard-story story-archived hidden" if article.archived %>">
<div class="dashboard-story__title">
<h3 class="flex items-center">
<% if article.archived %>
<span class="crayons-indicator crayons-indicator--critical mr-2 fw-normal">Archived</span>
<% end %>
<a href="<%= article.current_state_path %>" class="inline-flex items-center">
<% if article.organization_id %>
<span class="crayons-logo crayons-logo--s mr-2"><img class="crayons-logo__image" src="<%= article.organization&.profile_image_90 %>" alt="<%= article.organization&.name %>" width="24" height="24"></span>
<span class="crayons-logo crayons-logo--s mr-2 shrink-0"><img class="crayons-logo__image align-top" src="<%= article.organization&.profile_image_90 %>" alt="<%= article.organization&.name %>" width="24" height="24"></span>
<% end %>
<%= sanitize_and_decode article.title %>
</a>
</h3>
<% if article.published %>
<% if article.cached_tag_list_array.any? %>
<div class="-ml-1">
<% article.cached_tag_list_array.each do |tag| %>
<a href="/t/<%= tag %>" class="crayons-tag"><span class="crayons-tag__prefix">#</span><%= tag %></a>
<% end %>
</div>
<% end %>
<p class="fs-s color-base-70 js-dashboard-story-details">
<p class="fs-s color-base-60 js-dashboard-story-details">
<strong class="fw-medium">Published:</strong> <time datetime="<%= article.published_timestamp %>"><%= article.readable_publish_date %></time>
<% if article.edited? %>
<strong class="fw-medium pl-2">Edited:</strong> <time datetime="<%= article.edited_at.utc.iso8601 %>"><%= article.readable_edit_date %></time>
@ -27,61 +22,53 @@
<% end %>
</p>
<% end %>
</td>
</div>
<td class="fs-s color-base-70">
<div class="flex flex-wrap <%= "opacity-25" unless article.published %>" data-analytics-pageviews data-article-id="<%= article.id %>">
<span class="flex items-center p-1" title="Reactions">
<%= inline_svg_tag("small-heart.svg", aria: true, class: "crayons-icon mr-1", title: "Reactions") %>
<% if article.published %>
<%= article.public_reactions_count %>
<% else %>
0
<% end %>
</span>
<span class="flex items-center p-1 ml-1" title="Comments">
<%= inline_svg_tag("small-comment.svg", aria: true, class: "crayons-icon mr-1", title: "Comments") %>
<span class="spec__comments-count">
<%= article.comments_count %>
</span>
</span>
<span class="flex items-center p-1 ml-1" title="Views">
<%= inline_svg_tag("small-eye.svg", aria: true, class: "crayons-icon mr-1", title: "Views") %>
<% if article.published %>
<% if article.page_views_count > 25 %>
<%= article.page_views_count %>
<% else %>
&lt; 25
<% end %>
<% else %>
0
<% end %>
</span>
<% if false %>
<span class="flex items-center p-1 ml-1" title="Data">
<%= inline_svg_tag("small-data.svg", aria: true, class: "crayons-icon mr-1", title: "Data") %>
4
</span>
<% end %>
</div>
</td>
<td>
<% if article.archived %>
<span class="crayons-indicator crayons-indicator--critical">Archived</span>
<div class="fs-s color-base-70">
<% if !article.published? %>
<a href="<%= article.path %>/edit" class="crayons-indicator crayons-indicator--accent">Draft</a>
<% else %>
<% if article.published %>
<span class="crayons-indicator">Published</span>
<% else %>
<a href="<%= article.path %>/edit" class="crayons-indicator crayons-indicator--accent">Draft</a>
<% end %>
<% end %>
</td>
<div class="flex flex-nowrap whitespace-nowrap" data-analytics-pageviews data-article-id="<%= article.id %>">
<span class="flex items-center p-1" title="Reactions">
<%= inline_svg_tag("small-heart.svg", aria: true, class: "crayons-icon mr-1", title: "Reactions") %>
<% if article.published %>
<%= article.public_reactions_count %>
<% else %>
0
<% end %>
</span>
<td class="align-right">
<span class="flex items-center p-1 ml-1" title="Comments">
<%= inline_svg_tag("small-comment.svg", aria: true, class: "crayons-icon mr-1", title: "Comments") %>
<span class="spec__comments-count">
<%= article.comments_count %>
</span>
</span>
<span class="flex items-center p-1 ml-1" title="Views">
<%= inline_svg_tag("small-eye.svg", aria: true, class: "crayons-icon mr-1", title: "Views") %>
<% if article.published %>
<% if article.page_views_count > 25 %>
<%= article.page_views_count %>
<% else %>
&lt; 25
<% end %>
<% else %>
0
<% end %>
</span>
<% if false %>
<span class="flex items-center p-1 ml-1" title="Data">
<%= inline_svg_tag("small-data.svg", aria: true, class: "crayons-icon mr-1", title: "Data") %>
4
</span>
<% end %>
</div>
<% end %>
</div>
<div class="dashboard-story__actions">
<% if manage_view %>
<a href="<%= article.path %>/delete_confirm" data-no-instant class="crayons-btn crayons-btn--ghost-danger crayons-btn--s">Delete</a>
@ -132,5 +119,5 @@
<% end %>
</div>
</div>
</td>
</tr>
</div>
</div>

View file

@ -1,14 +0,0 @@
<h1>
<a class="rounded-btn <%= "active" if params[:action] == "following_tags" %>" href="/dashboard/following_tags">
<span>tags (<%= @user.following_tags_count %>)</span>
</a>
<a class="rounded-btn <%= "active" if params[:action] == "following_users" %>" href="/dashboard/following_users">
<span>users (<%= @user.following_users_count %>)</span>
</a>
<a class="rounded-btn <%= "active" if params[:action] == "following_organizations" %>" href="/dashboard/following_organizations">
<span>organizations (<%= @user.following_organizations_count %>)</span>
</a>
<a class="rounded-btn <%= "active" if params[:action] == "following_podcasts" %>" href="/dashboard/following_podcasts">
<span>podcasts (<%= @user.following_podcasts_count %>)</span>
</a>
</h1>

View file

@ -1,44 +1,63 @@
<% title("Dashboard - #{community_name}") %>
<div id="index-container"
<main id="index-container"
data-params="<%= params.to_json(only: %i[which per_page]) %>"
data-which="followers">
<div class="dashboard-container crayons-layout" id="user-dashboard">
<%= render "actions" %>
<% if @organizations && (params[:which].blank? || params[:which] == "organization") %>
<h1>
<a href="/dashboard" class="rounded-btn <%= "active" if params[:which].blank? %>">Personal</a>
<% @organizations.each do |org| %>
<a href="/dashboard/organization/<%= org.id %>" class="rounded-btn <%= "active" if params[:org_id].to_i == org.id %>"><%= org.name %> (<%= org.articles.size %>)</a>
<% end %>
<% if @user.has_role? :pro %>
<br>
<a class="rounded-btn" href="/dashboard/pro">Pro Analytics</a>
<% @organizations.each do |org| %>
<a class="rounded-btn" href="/dashboard/pro/org/<%= org.id %>">Pro Analytics for <%= org.name %></a>
<header class="crayons-layout">
<h1 class="p-2 pb-0 m:p-0">Dashboard &raquo; Followers</h1>
<%= render "actions_mobile" %>
</header>
<div class="crayons-layout crayons-layout--2-cols">
<aside class="crayons-layout__sidebar-left">
<%= render "actions" %>
</aside>
<div class="crayons-layout__content" id="user-dashboard">
<% if @follows.any? %>
<div id="following-wrapper" class="grid gap-0 s:gap-3 m:gap-4 s:grid-cols-2 l:grid-cols-3 align-left s:align-center">
<% @follows.each do |follow| %>
<% user = follow.follower %>
<% if user %>
<div class="crayons-card p-4 m:p-6 flex s:grid single-article" id="follows-<%= follow.id %>">
<a href="<%= user.path %>" class="crayons-avatar crayons-avatar--2xl s:mb-2 s:mx-auto">
<img alt="<%= user.username %> profile image" class="crayons-avatar__image" src="<%= ProfileImage.new(user).get(width: 60) %>" />
</a>
<div class="pl-4 s:pl-0 self-center">
<h3 class="s:mb-1 p-0">
<a href="<%= user.path %>">
<%= user.name %>
</a>
</h3>
<p class="s:mb-4">
<a href="<%= user.path %>" class="crayons-link crayons-link--secondary">
@<%= user.username %>
</a>
</p>
</div>
</div>
<% end %>
<% end %>
<% end %>
</h1>
<% end %>
<% @follows.each do |follow| %>
<% user = follow.follower %>
<% if user %>
<div id="follows-<%= follow.id %>" class="single-article">
<h2>
<a href="<%= user.path %>" class="block-link">
<img alt="<%= user.username %> profile image" src="<%= ProfileImage.new(user).get(width: 60) %>" />
<%= user.name %>
<span class="dashboard-username">@<%= user.username %></span>
</a>
<button class="cta follow-action-button dashboard-follow follow-user"
data-info='{"id":<%= user.id %>,"className":"<%= user.class.name %>","style":"follow-back"}'>
&nbsp;
</button>
</h2>
</div>
<% else %>
<div class="p-9 crayons-card crayons-card--secondary align-center fs-l">You don't have any followers yet...</div>
<% end %>
</div>
<div>
<div class="dashboard-container crayons-layout" id="user-dashboard">
<% if @organizations && (params[:which].blank? || params[:which] == "organization") %>
<select id="dashboard_author" class="crayons-select w-auto ml-2">
<option value="/dashboard" <%= "selected" if params[:which].blank? %>>Personal</option>
<% @organizations.each do |org| %>
<option value="/dashboard/organization/<%= org.id %>" <%= "selected" if params[:org_id].to_i == org.id %>><%= org.name %> (<%= org.articles.size %>)</option>
<% end %>
</select>
<% end %>
<%= render "sublist" %>
</div>
</div>
</main>

View file

@ -1,26 +1,49 @@
<% title("Dashboard - #{community_name}") %>
<div id="index-container"
<main id="index-container"
data-params="<%= params.to_json(only: %i[action per_page]) %>"
data-which="following">
<div class="dashboard-container crayons-layout" id="user-dashboard">
<%= render "actions" %>
<header class="crayons-layout">
<h1 class="p-2 pb-0 m:p-0">Dashboard &raquo; Following organizations</h1>
<%= render "actions_mobile" %>
</header>
<%= render "subactions" %>
<div class="crayons-layout crayons-layout--2-cols">
<aside class="crayons-layout__sidebar-left">
<%= render "actions" %>
</aside>
<% @followed_organizations.each do |follow| %>
<% organization = follow.followable %>
<div id="follows-<%= follow.id %>" class="single-article">
<a href="<%= organization.path %>" class="block-link">
<h2>
<img alt="<%= organization.name %> profile image" src="<%= ProfileImage.new(organization).get(width: 60) %>" />
<%= organization.name %>
<span class="dashboard-username">@<%= organization.username %></span>
</h2>
</a>
</div>
<% end %>
<div class="crayons-layout__content" id="user-dashboard">
<%= render "sublist" %>
<% if @followed_organizations.any? %>
<div id="following-wrapper" class="grid gap-0 s:gap-3 m:gap-4 s:grid-cols-2 l:grid-cols-3 align-left s:align-center">
<% @followed_organizations.each do |follow| %>
<% organization = follow.followable %>
<div class="crayons-card p-4 m:p-6 flex s:grid single-article" id="follows-<%= follow.id %>">
<a href="<%= organization.path %>" class="crayons-logo crayons-logo--2xl s:mb-2 s:mx-auto">
<img alt="<%= organization.name %> logo" class="crayons-logo__image" src="<%= ProfileImage.new(organization).get(width: 60) %>" />
</a>
<div class="pl-4 s:pl-0 self-center">
<h3 class="s:mb-1 p-0">
<a href="<%= organization.path %>">
<%= organization.name %>
</a>
</h3>
<p>
<a href="<%= organization.path %>" class="crayons-link crayons-link--secondary">
@<%= organization.username %>
</a>
</p>
</div>
</div>
<% end %>
</div>
<% else %>
<div class="p-9 crayons-card crayons-card--secondary align-center fs-l h-100 flex items-center justify-center">You don't follow any organizations yet...</div>
<% end %>
<%= render "sublist" %>
</div>
</div>
</div>
</main>

View file

@ -1,28 +1,49 @@
<% title("Dashboard - #{community_name}") %>
<div id="index-container"
<main id="index-container"
data-params="<%= params.to_json(only: %i[action per_page]) %>"
data-which="following">
<div class="dashboard-container crayons-layout" id="user-dashboard">
<%= render "actions" %>
<header class="crayons-layout">
<h1 class="p-2 pb-0 m:p-0">Dashboard &raquo; Following podcasts</h1>
<%= render "actions_mobile" %>
</header>
<%= render "subactions" %>
<div class="crayons-layout crayons-layout--2-cols">
<aside class="crayons-layout__sidebar-left">
<%= render "actions" %>
</aside>
<% @followed_podcasts.each do |follow| %>
<% podcast = follow.followable %>
<% if podcast %>
<div id="follows-<%= follow.id %>" class="single-article">
<a href="/<%= podcast.path %>" class="block-link">
<h2>
<img alt="<%= podcast.name %> profile image" src="<%= podcast.image_url %>" />
<%= podcast.name %>
<span class="dashboard-username">@<%= podcast.name %></span>
</h2>
</a>
<div class="crayons-layout__content" id="user-dashboard">
<% if @followed_podcasts.any? %>
<div id="following-wrapper" class="grid gap-0 s:gap-3 m:gap-4 s:grid-cols-2 l:grid-cols-3 align-left s:align-center">
<% @followed_podcasts.each do |follow| %>
<% podcast = follow.followable %>
<div class="crayons-card p-4 m:p-6 flex s:grid single-article" id="follows-<%= follow.id %>">
<a href="/<%= podcast.path %>" class="crayons-logo crayons-logo--2xl s:mb-2 s:mx-auto">
<img alt="<%= podcast.name %> logo" class="crayons-logo__image" src="<%= podcast.image_url %>" />
</a>
<div class="pl-4 s:pl-0 self-center">
<h3 class="s:mb-1 p-0">
<a href="/<%= podcast.path %>">
<%= podcast.name %>
</a>
</h3>
<p>
<a href="/<%= podcast.path %>" class="crayons-link crayons-link--secondary">
@<%= podcast.name %>
</a>
</p>
</div>
</div>
<% end %>
</div>
<% else %>
<div class="p-9 crayons-card crayons-card--secondary align-center fs-l h-100 flex items-center justify-center">You don't follow any podcasts yet...</div>
<% end %>
<% end %>
<%= render "sublist" %>
<%= render "sublist" %>
</div>
</div>
</div>
</main>

View file

@ -1,42 +1,52 @@
<% title("Dashboard - #{community_name}") %>
<div id="index-container"
<main id="index-container"
data-params="<%= params.to_json(only: %i[action per_page]) %>"
data-which="following">
<div class="dashboard-container crayons-layout" id="user-dashboard">
<%= render "actions" %>
<header class="crayons-layout">
<h1 class="p-2 pb-0 m:p-0">Dashboard &raquo; Following tags</h1>
<%= render "actions_mobile" %>
</header>
<%= render "subactions" %>
<div class="crayons-layout crayons-layout--2-cols">
<aside class="crayons-layout__sidebar-left">
<%= render "actions" %>
</aside>
<p><em>Adjust <strong>Follow Weight</strong> to make a tag show up less or more in your feed (default 1.0)</em>
</p>
<% negative_follow_shown_once = false %>
<% @followed_tags.each do |follow| %>
<% tag = follow.followable %>
<% if tag %>
<% if follow.points < 0 && !negative_follow_shown_once %>
<h2>Negative Tags (anti-follows)</h2>
<% negative_follow_shown_once = true %>
<% end %>
<% color = HexComparer.new([tag.bg_color_hex || "#0000000", tag.text_color_hex || "#ffffff"]).brightness(0.8) %>
<div id="follows-<%= follow.id %>" class="single-article" style="border: 1px solid <%= color %>;box-shadow: 3px 3px 0px <%= color %>">
<h2>
<a href="/t/<%= tag.name %>">
<%= tag.name %>
</a>
<div class="follow-tag-actions">
<%= form_for(follow) do |f| %>
<%= f.label(:points, "Follow Weight:") %>
<%= f.number_field(:points, step: :any, required: true) %>
<%= f.submit "Submit" %>
<% end %>
<button class="cta follow-action-button dashboard-follow follow-tag" data-info='{"id":<%= tag.id %>,"className":"Tag"}'>&nbsp;</button>
</div>
</h2>
<div class="crayons-layout__content" id="user-dashboard">
<% if @followed_tags.any? %>
<div class="crayons-card crayons-card--secondary p-4 px-6 fs-s mb-2 mx-2 m:mx-0">Adjust <strong>Follow Weight</strong> to make a tag show up less or more in your feed (default 1.0)</div>
<div id="following-wrapper" class="grid gap-3 m:gap-4 s:grid-cols-2 l:grid-cols-3 px-2 m:px-0">
<% negative_follow_shown_once = false %>
<% @followed_tags.each do |follow| %>
<% tag = follow.followable %>
<% if tag %>
<% color = HexComparer.new([tag.bg_color_hex || "#0000000", tag.text_color_hex || "#ffffff"]).brightness(0.8) %>
<div class="crayons-card p-4 m:p-6 flex flex-col single-article <% if follow.points < 0 %>opacity-75<% end %>" style="border: 1px solid <%= color %>;box-shadow: 3px 3px 0px <%= color %>" id="follows-<%= follow.id %>">
<h3 class="s:mb-1 p-0 fw-medium">
<a href="/t/<%= tag.name %>" class="crayons-tag crayons-tag--l">
<span class="crayons-tag__prefix">#</span><%= tag.name %>
</a>
<% if follow.points < 0 %>
<span class="crayons-indicator crayons-indicator--critical crayons-indicator--outlined" title="This tag has negative follow weight">Anti-follow</span>
<% end %>
</h3>
<p class="grid-cell__summary"><%= tag.short_summary %></p>
<%= form_for(follow, html: { class: "flex items-center flex-nowrap mb-4" }) do |f| %>
<%= f.label(:points, "Follow weight:", class: "fs-s flex-1 pr-2 color-base-60 align-right whitespace-nowrap") %>
<%= f.number_field(:points, step: :any, required: true, class: "crayons-textfield flex-1 fs-s", style: "max-width:90px") %>
<button type="submit" class="crayons-btn crayons-btn--ghost crayons-btn--s" name="commit">Save</button>
<% end %>
</div>
<% end %>
<% end %>
</div>
<% else %>
<div class="p-9 crayons-card crayons-card--secondary align-center fs-l h-100 flex items-center justify-center">You don't follow any tags yet...</div>
<% end %>
<% end %>
<%= render "sublist" %>
<%= render "sublist" %>
</div>
</div>
</div>
</main>

View file

@ -1,29 +1,51 @@
<% title("Dashboard - #{community_name}") %>
<div id="index-container"
<main id="index-container"
data-params="<%= params.to_json(only: %i[action per_page]) %>"
data-which="following">
<div class="dashboard-container crayons-layout" id="user-dashboard">
<%= render "actions" %>
<header class="crayons-layout">
<h1 class="p-2 pb-0 m:p-0">Dashboard &raquo; Following users</h1>
<%= render "actions_mobile" %>
</header>
<%= render "subactions" %>
<div class="crayons-layout crayons-layout--2-cols">
<aside class="crayons-layout__sidebar-left">
<%= render "actions" %>
</aside>
<% @follows.each do |follow| %>
<% user = follow.followable %>
<% if user %>
<div id="follows-<%= follow.id %>" class="single-article">
<h2>
<a href="<%= user.path %>" class="block-link">
<img alt="<%= user.username %> profile image" src="<%= ProfileImage.new(user).get(width: 60) %>" />
<%= user.name %>
<span class="dashboard-username">@<%= user.username %></span>
</a>
<button class="cta follow-action-button dashboard-follow follow-user" data-info='{"id":<%= user.id %>,"className":"<%= user.class.name %>"}'>&nbsp;</button>
</h2>
<div class="crayons-layout__content" id="user-dashboard">
<% if @follows.any? %>
<div id="following-wrapper" class="grid gap-0 s:gap-3 m:gap-4 s:grid-cols-2 l:grid-cols-3 align-left s:align-center">
<% @follows.each do |follow| %>
<% user = follow.followable %>
<% if user %>
<div class="crayons-card p-4 m:p-6 flex s:grid single-article" id="follows-<%= follow.id %>">
<a href="<%= user.path %>" class="crayons-avatar crayons-avatar--2xl s:mb-2 s:mx-auto">
<img alt="<%= user.username %> profile image" class="crayons-avatar__image" src="<%= ProfileImage.new(user).get(width: 60) %>" />
</a>
<div class="pl-4 s:pl-0 self-center">
<h3 class="s:mb-1 p-0">
<a href="<%= user.path %>">
<%= user.name %>
</a>
</h3>
<p class="s:mb-4">
<a href="<%= user.path %>" class="crayons-link crayons-link--secondary">
@<%= user.username %>
</a>
</p>
</div>
</div>
<% end %>
<% end %>
</div>
<% else %>
<div class="p-9 crayons-card crayons-card--secondary align-center fs-l h-100 flex items-center justify-center">You don't follow any users...</div>
<% end %>
<% end %>
<%= render "sublist" %>
<%= render "sublist" %>
</div>
</div>
</div>
</main>

View file

@ -1,88 +1,72 @@
<% title "Dashboard" %>
<main class="dashboard-container crayons-layout" id="user-dashboard">
<h1 class="visually-hidden-header">User Dashboard</h1>
<%= render "actions" %>
<% if @organizations && @organizations.size > 0 && (params[:which].blank? || params[:which] == "organization") %>
<h1>
<a href="/dashboard" class="rounded-btn <%= "active" if params[:which].blank? %>">Personal</a>
<% @organizations.each do |org| %>
<a href="/dashboard/organization/<%= org.id %>" class="rounded-btn <%= "active" if params[:org_id].to_i == org.id %>"><%= org.name %> (<%= org.articles_count %>)</a>
<% end %>
</h1>
<% end %>
<% if params[:which] == "organization" %>
<main>
<header class="crayons-layout">
<h1 class="p-2 pb-0 m:p-0">Dashboard</h1>
<%= render "actions_mobile" %>
<%= render "analytics" %>
</header>
<table class="crayons-table mb-6" width="100%" border="0" cellpadding="0" cellspacing="0">
<thead>
<tr>
<th>Post</th>
<th>Engagement</th>
<th>Status</th>
<th></th>
</tr>
</thead>
<div class="crayons-layout crayons-layout--2-cols">
<aside class="crayons-layout__sidebar-left">
<%= render "actions" %>
</aside>
<tbody class="crayons-card">
<% @articles.each do |article| %>
<%= render "dashboard_article_row", article: article, organization: article.organization, org_admin: true, manage_view: false %>
<% end %>
</tbody>
</table>
<% elsif @articles.any? %>
<%= render "analytics" %>
<div class="actions-secondary">
<% if current_user.created_at < 2.weeks.ago %>
<a class="video-upload-cta cta" href="/videos/new" data-no-instant>
Upload a Video 🎥
</a>
<% end %>
<a class="video-upload-cta cta" href="/listings/dashboard" data-no-instant>
Create/Manage Listings
</a>
<%= select_tag "dashboard_sort", options_for_select(sort_options, params[:sort]), 'aria-label': "Sort By" %>
<% if @articles.any? {|article| article.archived } %>
<%= link_to "Show archived", "javascript:;", id: "toggleArchivedLink" %>
<div class="crayons-layout__content">
<% if @articles.any? %>
<div class="flex items-center justify-between mb-3">
<h2 class="hidden m:block fs-l fw-heavy">Posts</h2>
<div class="flex flex-wrap">
<% if params[:which] != "organization" %>
<% if @articles.any? {|article| article.archived } %>
<%= link_to "Show archived", "javascript:;", id: "toggleArchivedLink", class: "crayons-btn crayons-btn--outlined ml-2 whitespace-nowrap my-1" %>
<% end %>
<%= select_tag "dashboard_sort", options_for_select(sort_options, params[:sort]), 'aria-label': "Sort By", class: "crayons-select w-auto ml-2 my-1" %>
<% end %>
<% if @organizations && @organizations.size > 0 && (params[:which].blank? || params[:which] == "organization") %>
<select id="dashboard_author" class="crayons-select w-auto ml-2 my-1">
<option value="/dashboard" <%= "selected" if params[:which].blank? %>>Personal</option>
<% @organizations.each do |org| %>
<option value="/dashboard/organization/<%= org.id %>" <%= "selected" if params[:org_id].to_i == org.id %>><%= org.name %> (<%= org.articles_count %>)</option>
<% end %>
</select>
<% end %>
</div>
</div>
<div class="crayons-card mb-6">
<% @articles.each do |article| %>
<% if params[:which] == "organization" %>
<%= render "dashboard_article_row", article: article, organization: article.organization, org_admin: true, manage_view: false %>
<% else %>
<%= render "dashboard_article_row", article: article, organization: nil, org_admin: false, manage_view: false %>
<% end %>
<% end %>
</div>
<div class="mb-4 pl-3">
<%= paginate @articles, params: { i: nil } %>
</div>
<% else %>
<div class="p-9 crayons-card crayons-card--secondary align-center fs-l h-100 flex items-center justify-center">
<div>
<%= image_tag(cl_image_path(SiteConfig.mascot_image_url,
type: "fetch",
width: 300,
crop: "imagga_scale",
quality: "auto",
flags: "progressive",
fetch_format: "auto",
sign_url: true), class: "sloan mb-7", alt: "Sloan, the sloth mascot") %>
<p class="mb-6">This is where you can manage your posts, but you haven't written anything yet.</p>
<p><a href="/new" class="crayons-btn crayons-btn--l">Write your first post now</a></p>
</div>
</div>
<% end %>
</div>
<table class="crayons-table mb-6" width="100%" border="0" cellpadding="0" cellspacing="0">
<thead>
<tr>
<th>Post</th>
<th>Engagement</th>
<th>Status</th>
<th></th>
</tr>
</thead>
<tbody class="crayons-card">
<% @articles.each do |article| %>
<%= render "dashboard_article_row", article: article, organization: nil, org_admin: false, manage_view: false %>
<% end %>
</tbody>
</table>
<div class="mb-4 pl-3">
<%= paginate @articles, params: { i: nil } %>
</div>
<% else %>
<div class="no-articles">
<h3>This is where you can manage your posts, but you haven't written anything yet.</h3>
<a href="/new" class="cta big">
Write your first post now
</a>
<%= image_tag(cl_image_path(SiteConfig.mascot_image_url,
type: "fetch",
width: 300,
crop: "imagga_scale",
quality: "auto",
flags: "progressive",
fetch_format: "auto",
sign_url: true), class: "sloan", alt: "Sloan, the sloth mascot") %>
<br />
<h3>Also check out the <a href="/welcome" data-no-instant>Welcome Thread</a> to introduce yourself!</h3>
</div>
<% end %>
</div>
</main>

View file

@ -120,7 +120,7 @@ RSpec.describe "Dashboards", type: :request do
end
it "renders followed users count" do
expect(response.body).to include "users (1)"
expect(response.body).to include "Following users (1)"
end
it "lists followed users" do
@ -139,7 +139,7 @@ RSpec.describe "Dashboards", type: :request do
end
it "renders followed tags count" do
expect(response.body).to include "tags (1)"
expect(response.body).to include "Following tags (1)"
end
it "lists followed tags" do
@ -158,7 +158,7 @@ RSpec.describe "Dashboards", type: :request do
end
it "renders followed organizations count" do
expect(response.body).to include "organizations (1)"
expect(response.body).to include "Following organizations (1)"
end
it "lists followed organizations" do
@ -177,7 +177,7 @@ RSpec.describe "Dashboards", type: :request do
end
it "renders followed podcast count" do
expect(response.body).to include "podcasts (1)"
expect(response.body).to include "Following podcasts (1)"
end
it "lists followed podcasts" do

View file

@ -11,7 +11,7 @@ RSpec.describe "Followers Dashboard", type: :system, js: true do
end
context "when /dashboard/user_followers is visited" do
it "displays correct following buttons" do
xit "displays correct following buttons" do
following_user.follow(user)
followed_user.follow(user)
user.follow(followed_user)

View file

@ -24,13 +24,11 @@ RSpec.describe "Link on tags for post in notifications", type: :system do
sign_in article.user
end
it "shows articles with tags", js: true, percy: true do
it "shows articles", js: true, percy: true do
visit "/dashboard"
Percy.snapshot(page, name: "Logged in user: dashboard")
expect(page).to have_selector(".spec__dashboard-story", count: 1)
expect(page).to have_link("#ruby", href: "/t/ruby")
expect(page).to have_link("#javascript", href: "/t/javascript")
end
end
end