Layout updates (#8107)

* flare tag line height

* .

* init

* widgets

* widgets lists

* new tabs on home

* instantclick

* .

* rethinking css

* .

* .

* empty space

* campaign widget

* .

* merge

* .

* update layout

* fix sidebars on home page

* .

* fix onboarding x

* spec

* test

* test

* better handling ads

* .

* spec

* card styling

* .

* i dont know what have i broken
This commit is contained in:
ludwiczakpawel 2020-06-04 16:12:17 +02:00 committed by GitHub
parent 8fb0641118
commit 39295c0bea
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
53 changed files with 763 additions and 641 deletions

View file

@ -207,7 +207,7 @@ function assignState(butt, newState) {
addFollowText(butt, style);
} else if (newState === 'self') {
butt.dataset.verb = 'self';
butt.textContent = 'EDIT PROFILE';
butt.textContent = 'Edit profile';
} else {
butt.dataset.verb = 'follow';
addFollowingText(butt, style);
@ -219,9 +219,9 @@ function addFollowText(butt, style) {
if (style === 'small') {
butt.textContent = '+';
} else if (style === 'follow-back') {
butt.textContent = '+ FOLLOW BACK';
butt.textContent = 'Follow back';
} else {
butt.textContent = '+ FOLLOW';
butt.textContent = 'Follow';
}
}
@ -229,6 +229,6 @@ function addFollowingText(butt, style) {
if (style === 'small') {
butt.textContent = '✓';
} else {
butt.textContent = '✓ FOLLOWING';
butt.textContent = 'Following';
}
}

View file

@ -20,8 +20,8 @@ function initializeUserSidebar(user) {
let followedTags = JSON.parse(user.followed_tags);
const tagSeparatorLabel =
followedTags.length === 0
? 'Follow tags to improve your feed'
: 'Other Popular Tags';
? 'FOLLOW TAGS TO IMPROVE YOUR FEED'
: 'OTHER POPULAR TAGS';
followedTags.forEach((tag) => {
const element = document.getElementById(

View file

@ -1,4 +1,4 @@
/* global timestampToLocalDateTime */
/* global timestampToLocalDateTime InstantClick */
function initializeSettings() {
// highlights organization secret on click
@ -27,4 +27,15 @@ function initializeSettings() {
timeOptions,
);
}
const mobilePageSelector = document.getElementById('mobile-page-selector');
if (mobilePageSelector) {
mobilePageSelector.addEventListener('change', (event) => {
const url = event.target.value;
InstantClick.preload(url);
InstantClick.display(url);
});
}
}

View file

@ -85,27 +85,13 @@
}
.sidebar-nav {
margin-bottom: 16px;
.sidebar-nav-block {
@media screen and (min-width: 950px) {
.sidebar-nav-block-inner {
height: 420px;
overflow-y: scroll;
overflow-x: hidden;
-webkit-overflow-scrolling: touch;
padding: 0 16px;
margin: 0 -16px 8px -16px;
}
}
.sidebar-nav-default-tags {
display: none;
&.showing {
display: block;
}
}
.sidebar-main-nav {
margin-bottom: 24px;
}
}
}
@ -125,6 +111,10 @@
}
}
.sidebar-tags-browser {
max-height: 420px;
}
@keyframes fade-in {
0% {
opacity: 0;
@ -357,7 +347,7 @@
}
// Generally Feed...
.articles-list {
.articles-list:not(.crayons-layout__content) {
margin: auto;
max-width: 100%;
position: relative;

View file

@ -1,28 +1,28 @@
@import '../config/import';
:root {
--layout-site-width: var(--site-width);
--layout-header-height: var(--header-height);
--layout-sidebar-width: 200px;
--layout-aside-width: 316px;
--layout-gap: var(--su-6);
--layout-padding: var(--su-6);
--layout-article-content-padding-x: var(--su-3);
--layout-article-content-padding-y: var(--su-3);
--layout-narrow-sidebar-width: 66px;
@media (min-width: $breakpoint-s) {
--layout-article-content-padding-x: var(--su-4);
--layout-article-content-padding-y: var(--su-4);
}
--layout-sidebar-left-display: block;
--layout-sidebar-right-display: block;
--layout-sidebar-left-width: 100%;
--layout-sidebar-right-width: 100%;
--layout-sidebar-left-row-end: initial;
--layout-content-width: 100%;
--layout-drawer-width: 300px;
--layout-gap: var(--su-2);
--layout-padding: 0;
--layout: 100%;
@media (min-width: $breakpoint-m) {
--layout-article-content-padding-x: var(--su-6);
--layout-article-content-padding-y: var(--su-6);
--layout-sidebar-left-width: 2fr;
--layout-padding: var(--su-2);
--layout: var(--layout-content-width);
}
@media (min-width: $breakpoint-l) {
--layout-article-content-padding-x: var(--su-8);
--layout-sidebar-left-width: 240px;
--layout-content-width: 1fr;
--layout-gap: var(--su-4);
--layout-padding: var(--su-4);
}
}
@ -31,17 +31,159 @@
width: 100%;
max-width: var(--site-width);
margin: 0 auto;
display: grid;
grid-gap: var(--layout-gap);
grid-template-columns: var(--layout);
padding: var(--layout-padding);
&--max-l {
max-width: $breakpoint-l;
&__sidebar-left {
display: var(--layout-sidebar-left-display);
grid-row-end: var(--layout-sidebar-left-row-end);
width: var(--layout-sidebar-left-width);
}
&__sidebar-right {
display: var(--layout-sidebar-right-display);
width: var(--layout-sidebar-right-width);
}
&__content__inner {
margin: 0 auto;
width: 100%;
}
&--limited {
--site-width: #{$breakpoint-l};
}
&--limited-inner {
.crayons-layout__content__inner {
max-width: $breakpoint-l;
}
}
}
.crayons-layout--default {
@media (min-width: $breakpoint-s) {
display: grid;
grid-gap: var(--layout-gap);
grid-template-columns: var(--layout-sidebar-width) 1fr;
padding: var(--layout-padding);
.crayons-layout--2-cols {
@media (min-width: $breakpoint-m) {
--layout: var(--layout-sidebar-left-width) var(--layout-content-width);
--layout-content-width: 5fr;
}
@media (min-width: $breakpoint-l) {
--layout-sidebar-left-width: 240px;
--layout-content-width: 1fr;
--layout-gap: var(--su-4);
}
&.crayons-layout--limited-inner {
.crayons-layout__content__inner {
max-width: $breakpoint-m;
margin: 0 auto;
width: 100%;
}
}
}
.crayons-layout--3-cols {
@media (min-width: $breakpoint-m) {
--layout: var(--layout-sidebar-left-width) var(--layout-content-width);
--layout-sidebar-left-row-end: span 2;
--layout-sidebar-left-width: 2fr;
--layout-sidebar-right-width: 5fr;
--layout-content-width: 5fr;
}
@media (min-width: $breakpoint-l) {
--layout-sidebar-left-width: 240px;
--layout-sidebar-right-width: 1fr;
--layout-sidebar-left-row-end: initial;
--layout-content-width: 2fr;
--layout: var(--layout-sidebar-left-width) var(--layout-content-width)
var(--layout-sidebar-right-width);
}
&--drop-right-left {
--layout-sidebar-left-display: none;
--layout-sidebar-right-display: none;
--layout-sidebar-left-width: var(--layout-drawer-width);
--layout-sidebar-right-width: var(--layout-drawer-width);
@media (min-width: $breakpoint-m) {
--layout-sidebar-left-width: 2fr;
--layout-sidebar-left-row-end: initial;
--layout-sidebar-left-display: block;
}
@media (min-width: $breakpoint-l) {
--layout-sidebar-right-display: block;
--layout-sidebar-right-width: 1fr;
--layout-sidebar-left-width: 240px;
}
}
}
.crayons-layout--article {
@media (min-width: $breakpoint-m) {
--layout-sidebar-left-width: var(--su-9);
--layout: var(--layout-sidebar-left-width) 1fr;
--layout-sidebar-left-row-end: span 2;
}
@media (min-width: $breakpoint-l) {
--layout-sidebar-right-width: 3fr;
--layout-sidebar-left-row-end: initial;
--layout-content-width: 7fr;
--layout: var(--layout-sidebar-left-width) var(--layout-content-width)
var(--layout-sidebar-right-width);
}
}
// Temporary solution for sidebar on mobile
.crayons-layout__sidebar-left,
.crayons-layout__sidebar-right {
.sidebar-bg {
top: 0;
left: 0;
right: 0;
bottom: 0;
overflow: hidden;
position: fixed;
background: rgba(0, 0, 0, 0.5);
animation: fade-in var(--transition-props);
display: none;
}
&.swiped-in {
z-index: 100;
display: block;
position: fixed;
top: var(--header-height);
bottom: 0;
-webkit-overflow-scrolling: touch;
.sidebar-bg {
display: block;
}
.side-bar {
position: relative;
background: var(--body-bg);
z-index: 2;
padding: 16px;
align-content: start;
height: 100%;
overflow-y: auto;
}
}
}
.crayons-layout__sidebar-left {
&.swiped-in {
left: 0;
}
}
.crayons-layout__sidebar-right {
&.swiped-in {
right: 0;
}
}

View file

@ -6,18 +6,33 @@ $card-divider: 1px solid var(--body-bg);
border-radius: var(--radius);
background: var(--card-bg);
color: var(--card-color);
box-shadow: 0 0 0 1px var(--card-border);
&--secondary {
background: var(--card-secondary-bg);
color: var(--card-secondary-color);
box-shadow: 0 0 0 1px var(--card-secondary-border);
}
&__header {
padding: var(--su-4) var(--su-4);
padding: var(--su-3) var(--su-4);
border-bottom: $card-divider;
display: flex;
justify-content: space-between;
align-items: center;
&__headline {
font-size: var(--fs-l);
font-weight: var(--fw-bold);
color: var(--base-100);
a {
color: inherit;
&:hover {
color: var(--link-color-hover);
}
}
}
}
&__subheader {

View file

@ -4,7 +4,7 @@
.crayons-story {
background: var(--card-bg);
font-size: var(--fs-base); // Todo: remove when ready.
box-shadow: $bold-shadow, 0 0 0 1px var(--story-border); // we will kill it at some point, don't worry. just not yet.
box-shadow: 0 0 0 1px var(--card-border);
@media (min-width: $breakpoint-m) {
border-radius: var(--radius);

View file

@ -68,10 +68,8 @@
////////////////////////////////////////////////////////////////////////////////////
// Main colors
--body-bg: #f9fafa; // todo: replace with `var(--base-10);` when ready.
--body-color: var(
--base-100
); // todo: replace with `var(--base-100);` when ready.
--body-bg: var(--base-10);
--body-color: var(--base-100);
--body-color-inverted: var(--base-inverted);
// Main content containers
@ -82,6 +80,8 @@
--card-secondary-bg: var(--base-0);
--card-secondary-color: var(--base-90);
--card-headline-color: var(--base-100);
--card-border: var(--base-a10);
--card-secondary-border: var(--base-a5);
// Header
--header-bg: var(--base-inverted);
@ -209,7 +209,6 @@
// Story
--story-comments-bg: var(--base-0);
--story-border: transparent;
// Select icon
--select-icon: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTEyIDE2TDYgMTBIMThMMTIgMTZaIiBmaWxsPSIjMDgwOTBBIi8+Cjwvc3ZnPg==);

View file

@ -4,6 +4,7 @@
.onboarding-task-card {
background: var(--accent-brand);
position: relative;
border-radius: var(--radius);
padding: var(--su-7) var(--su-8) var(--su-8) var(--su-8);
display: none;

View file

@ -72,6 +72,8 @@
--card-secondary-bg: var(--base-inverted);
--card-secondary-color: var(--base-90);
--card-headline-color: var(--accent-brand-lighter);
--card-border: rgba(255, 255, 255, 0.2);
--card-secondary-border: rgba(255, 255, 255, 0.2);
// Header
--header-bg: var(--base-10);
@ -199,7 +201,6 @@
// Story
--story-comments-bg: #0d0d0d;
--story-border: rgba(255, 255, 255, 0.2);
// Select icon
--select-icon: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTEyIDE2TDYgMTBIMThMMTIgMTZaIiBmaWxsPSIjMkVGRjdCIi8+Cjwvc3ZnPg==);

View file

@ -70,6 +70,8 @@
--card-secondary-bg: var(--base-0);
--card-secondary-color: var(--base-90);
--card-headline-color: var(--base-100);
--card-border: var(--base-a5);
--card-secondary-border: var(--base-a5);
// Header
--header-bg: var(--base-0);
@ -197,7 +199,6 @@
// Story
--story-comments-bg: #fafafa; //hotfix
--story-border: transparent;
// Select icon
--select-icon: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTEyIDE2TDYgMTBIMThMMTIgMTZaIiBmaWxsPSIjN2E3YTdhIi8+Cjwvc3ZnPg==);

View file

@ -72,6 +72,8 @@
--card-secondary-bg: var(--base-a5);
--card-secondary-color: var(--base-90);
--card-headline-color: var(--base-100);
--card-border: rgba(255, 255, 255, 0.15);
--card-secondary-border: rgba(255, 255, 255, 0.1);
// Header
--header-bg: var(--base-10);
@ -199,7 +201,6 @@
// Story
--story-comments-bg: #151e2a; //hotfix
--story-border: rgba(255, 255, 255, 0.15);
// Select icon
--select-icon: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTEyIDE2TDYgMTBIMThMMTIgMTZaIiBmaWxsPSIjYzJjNmNhIi8+Cjwvc3ZnPg==);

View file

@ -67,9 +67,11 @@
--card-color: var(--base-100);
--card-color-secondary: var(--base-70);
--card-color-tertiary: var(--base-50);
--card-secondary-bg: var(--base-0);
--card-secondary-bg: rgba(255, 209, 223, 0.3);
--card-secondary-color: var(--base-90);
--card-headline-color: var(--base-100);
--card-border: var(--accent-brand);
--card-secondary-border: #{rgba(#ff6c9b, 0.2)};
// Header
--header-bg: var(--base-40);
@ -197,7 +199,6 @@
// Story
--story-comments-bg: rgba(255, 255, 255, 0.05);
--story-border: var(--accent-brand);
// Select icon
--select-icon: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTEyIDE2TDYgMTBIMThMMTIgMTZaIiBmaWxsPSIjNTcxOTJkIi8+Cjwvc3ZnPg==);

View file

@ -25,11 +25,17 @@
}
&__container {
max-width: $max-width;
max-width: var(--site-width);
padding-left: var(--su-2);
padding-right: var(--layout-padding);
margin: auto;
display: flex;
align-items: center;
position: relative;
@media (min-width: $breakpoint-m) {
padding-left: var(--layout-padding);
}
}
.crayons-indicator {
@ -43,10 +49,6 @@
// Logo
.top-bar--logo {
display: flex;
margin-left: var(--su-2);
@media (min-width: $breakpoint-m) {
margin-left: var(--su-4);
}
.logo {
width: 50px;

View file

@ -1,7 +1,7 @@
@import '../config/import';
%layout {
max-width: var(--layout-site-width);
max-width: 1280px;
width: 100%;
margin: 0 auto;
}
@ -23,108 +23,102 @@
.crayons-article-form {
--article-form-actions-height: 56px;
--layout-padding: var(--su-2);
max-width: var(--site-width);
display: grid;
padding: 0 var(--layout-padding);
height: 100vh;
grid-template-rows: min-content 1fr min-content;
background: var(--body-bg);
gap: 0 var(--layout-gap);
margin: 0 auto;
font-size: var(--fs-base);
grid-template-columns: 100%;
grid-template-rows: min-content 1fr min-content;
&__logo,
&__aside {
display: none;
@media (min-width: $breakpoint-m) {
display: block;
}
}
@media (min-width: $breakpoint-s) {
--article-form-actions-height: 72px;
}
@media (min-width: $breakpoint-m) {
grid-template-columns: 64px 7fr 3fr;
}
@media (min-width: $breakpoint-l) {
--article-form-actions-height: 88px;
}
&__header {
@extend %layout;
display: flex;
align-items: center;
padding: 0 var(--layout-padding);
height: var(--layout-header-height);
height: var(--header-height);
padding: 0 var(--su-2);
@media (min-width: $breakpoint-m) {
grid-column-end: span 2;
padding: 0;
}
@media (min-width: $breakpoint-l) {
padding-right: calc(
var(--layout-aside-width) + var(--layout-padding) + var(--layout-gap)
);
grid-column-start: 1;
grid-column-end: 3;
}
}
&__main {
@extend %layout;
&__content {
display: flex;
flex-direction: column;
height: 100%;
padding: var(--article-padding-y) var(--article-padding-x);
overflow: auto;
height: calc(
100vh - var(--header-height) - var(--article-form-actions-height)
);
box-shadow: 0 0 0 1px var(--card-border);
@media (min-width: $breakpoint-m) {
padding: 0 var(--layout-padding);
grid-column-end: span 2;
}
@media (min-width: $breakpoint-l) {
display: grid;
grid-gap: var(--layout-gap);
grid-template-columns:
calc(100% - var(--layout-aside-width) - var(--layout-gap))
var(--layout-aside-width);
grid-column-start: 2;
grid-column-end: 2;
}
}
@media (min-width: $breakpoint-xl) {
padding-left: calc(
var(--layout-narrow-sidebar-width) + var(--layout-padding)
);
}
&__aside {
display: none;
&__content {
display: flex;
flex-direction: column;
height: 100%;
padding: var(--layout-article-content-padding-y)
var(--layout-article-content-padding-x);
@media (min-width: $breakpoint-s) {
overflow: auto;
height: calc(
100vh - var(--layout-header-height) -
var(--article-form-actions-height)
);
}
@media (min-width: $breakpoint-m) {
border: 1px solid var(--base-10);
}
}
&__aside {
display: none;
@media (min-width: $breakpoint-l) {
display: block;
}
@media (min-width: $breakpoint-m) {
display: block;
}
}
&__footer {
@extend %layout;
background: var(--body-bg);
position: sticky;
bottom: 0;
padding: 0 var(--layout-padding);
height: var(--article-form-actions-height);
display: flex;
align-items: center;
padding: 0 var(--su-2);
@media (min-width: $breakpoint-xl) {
padding-left: calc(
var(--layout-narrow-sidebar-width) + var(--layout-padding)
);
@media (min-width: $breakpoint-m) {
padding: 0;
}
@media (min-width: $breakpoint-l) {
grid-column-start: 2;
grid-column-end: span 2;
}
}
}
.crayons-article-form {
&__logo {
display: flex;
margin-right: var(--su-1);
@media (min-width: $breakpoint-s) {
margin-right: var(--layout-gap);
@ -137,6 +131,7 @@
background: var(--logo-bg);
fill: var(--logo-color);
border-radius: var(--radius);
display: block;
}
}
@ -167,16 +162,12 @@
&__toolbar {
position: sticky;
top: 0;
top: calc(var(--article-padding-y) * -1);
background: var(--base-0);
padding: var(--su-2) var(--layout-article-content-padding-x);
margin: calc(var(--layout-article-content-padding-y) * -1)
calc(var(--layout-article-content-padding-x) * -1) var(--su-6)
calc(var(--layout-article-content-padding-x) * -1);
@media (min-width: $breakpoint-s) {
top: calc(var(--layout-article-content-padding-y) * -1);
}
padding: var(--su-2) var(--article-padding-x);
margin: calc(var(--article-padding-y) * -1)
calc(var(--article-padding-x) * -1) var(--su-6)
calc(var(--article-padding-x) * -1);
> :first-child {
margin-left: calc(var(--su-2) * -1);
@ -184,7 +175,7 @@
}
&__cover {
margin-bottom: var(--su-6);
margin-bottom: var(--su-4);
display: flex;
align-items: flex-start;
flex-direction: column;
@ -192,6 +183,7 @@
@media (min-width: $breakpoint-s) {
flex-direction: row;
align-items: center;
margin-bottom: var(--su-5);
}
&__image {
@ -215,7 +207,7 @@
&__tagsfield {
position: relative;
margin-bottom: calc(var(--su-7) + var(--layout-article-content-padding-y));
margin-bottom: calc(var(--article-padding-y) * 2);
}
&__help {

View file

@ -2,19 +2,31 @@
:root {
--article-rythm: var(--su-2);
--article-padding-x: var(--su-3);
--article-padding-y: var(--su-3);
@media (min-width: $breakpoint-s) {
--article-padding-x: var(--su-4);
--article-padding-y: var(--su-4);
}
@media (min-width: $breakpoint-m) {
--article-rythm: var(--su-4);
--article-padding-x: var(--su-6);
--article-padding-y: var(--su-6);
}
@media (min-width: $breakpoint-l) {
--article-padding-x: var(--su-8);
}
}
.crayons-article {
&__cover {
margin: calc(var(--layout-article-content-padding-y) * -1)
calc(var(--layout-article-content-padding-x) * -1)
var(--layout-article-content-padding-x)
calc(var(--layout-article-content-padding-x) * -1);
width: calc(100% + (var(--layout-article-content-padding-x) * 2));
margin: calc(var(--article-padding-y) * -1)
calc(var(--article-padding-x) * -1) var(--article-padding-x)
calc(var(--article-padding-x) * -1);
width: calc(100% + (var(--article-padding-x) * 2));
&__image {
border-radius: var(--radius) var(--radius) 0 0;

View file

@ -8,6 +8,7 @@
@include sidebar-link;
margin: 0;
margin-bottom: var(--su-2);
padding: var(--su-2);
display: flex;
align-items: center;
@ -441,7 +442,6 @@
// Left Side bar navigation links
// Pulling this out of context because Nick says so: https://github.com/thepracticaldev/dev.to/pull/5918/commits/f1642e62accbdaff72dc7762e1e1ffd4e40027b0
.sidebar-nav-element {
color: $black;
display: block;
position: relative;
@media screen and (min-width: $breakpoint-m) {
@ -478,15 +478,9 @@
}
a.sidebar-nav-link-follow {
position: absolute;
color: $black;
right: 5px;
top: 50%;
transform: translateY(-50%);
text-align: center;
border-radius: 3px;
font-weight: 900;
font-size: 0.8em;
padding: 2px 8px;
}
}
@ -511,3 +505,13 @@
color: var(--link-color-secondary);
}
}
.crayons-sponsorship-widget {
img {
width: 100%;
height: auto;
border-radius: var(--radius);
display: inline-block;
vertical-align: middle;
}
}

View file

@ -7,7 +7,7 @@ exports[`<ArticleForm /> renders properly 1`] = `
onInput={[Function]}
>
<div
class="crayons-article-form__header crayons-layout"
class="crayons-article-form__header"
>
<a
aria-label="Home"
@ -38,7 +38,7 @@ exports[`<ArticleForm /> renders properly 1`] = `
class="crayons-field__label flex items-center flex-1"
>
<span
class="hidden s:inline-block whitespace-nowrap"
class="hidden s:inline-block mr-2 whitespace-nowrap"
>
Write a new post
</span>
@ -91,164 +91,160 @@ exports[`<ArticleForm /> renders properly 1`] = `
</div>
</div>
<div
class="crayons-article-form__main"
class="crayons-article-form__content crayons-card"
>
<div
class="crayons-article-form__main__content crayons-card"
>
<div>
<div>
<div
class="crayons-article-form__cover"
role="presentation"
>
<div
class="crayons-article-form__cover"
role="presentation"
class="flex items-center"
>
<div
class="flex items-center"
<button
class="crayons-btn crayons-btn--outlined mr-2 whitespace-nowrap"
disabled={false}
type="button"
>
<button
class="crayons-btn crayons-btn--outlined mr-2 whitespace-nowrap"
disabled={false}
type="button"
<label
htmlFor="cover-image-input"
>
<label
htmlFor="cover-image-input"
>
Add a cover image
</label>
<input
accept="image/*"
class="w-100 h-100 absolute left-0 right-0 top-0 bottom-0 overflow-hidden opacity-0 cursor-pointer"
data-max-file-size-mb="25"
id="cover-image-input"
onChange={[Function]}
type="file"
/>
</button>
</div>
</div>
<div
class="crayons-article-form__title"
>
<textarea
autoComplete="off"
autofocus="true"
class="crayons-textfield crayons-textfield--ghost fs-3xl s:fs-4xl l:fs-5xl fw-bold s:fw-heavy lh-tight"
id="article-form-title"
onChange={[Function]}
onFocus={[Function]}
onInput={[Function]}
onKeyDown={[Function]}
placeholder="New post title here..."
ref={[Function]}
style={
Object {
"height": 0,
}
}
type="text"
value=""
/>
</div>
<div
class="crayons-article-form__tagsfield"
>
<div
class="crayons-article-form__tagswrapper"
>
Add a cover image
</label>
<input
autoComplete="off"
class="crayons-textfield crayons-textfield--ghost ff-accent crayons-article-form__tags"
id="tag-input"
name="listing[tag_list]"
onBlur={[Function]}
onFocus={[Function]}
onInput={[Function]}
onKeyDown={[Function]}
placeholder="Add up to 4 tags..."
ref={[Function]}
type="text"
value=""
accept="image/*"
class="w-100 h-100 absolute left-0 right-0 top-0 bottom-0 overflow-hidden opacity-0 cursor-pointer"
data-max-file-size-mb="25"
id="cover-image-input"
onChange={[Function]}
type="file"
/>
</div>
</button>
</div>
</div>
<div
class="crayons-article-form__body"
class="crayons-article-form__title"
>
<div
class="crayons-article-form__toolbar false"
>
<div
class="flex items-center"
>
<button
class="crayons-btn crayons-btn--ghost crayons-btn--icon-left mr-2 fw-normal"
disabled={false}
tabIndex="-1"
type="button"
>
<svg
aria-labelledby="a17qec5pfhrwzk9w4kg0tp62v27qqu9t"
class="crayons-icon"
height="24"
role="img"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<title
id="a17qec5pfhrwzk9w4kg0tp62v27qqu9t"
>
Upload image
</title>
<path
d="M20 5H4v14l9.292-9.294a1 1 0 011.414 0L20 15.01V5zM2 3.993A1 1 0 012.992 3h18.016c.548 0 .992.445.992.993v16.014a1 1 0 01-.992.993H2.992A.993.993 0 012 20.007V3.993zM8 11a2 2 0 110-4 2 2 0 010 4z"
/>
</svg>
Upload image
<input
accept="image/*"
class="w-100 h-100 absolute left-0 right-0 top-0 bottom-0 overflow-hidden opacity-0 cursor-pointer"
data-max-file-size-mb="25"
id="image-upload-field"
multiple={true}
onChange={[Function]}
tabIndex="-1"
type="file"
/>
</button>
</div>
</div>
<textarea
class="crayons-textfield crayons-textfield--ghost crayons-article-form__body__field"
id="article_body_markdown"
name="body_markdown"
autoComplete="off"
autofocus="true"
class="crayons-textfield crayons-textfield--ghost fs-3xl s:fs-4xl l:fs-5xl fw-bold s:fw-heavy lh-tight"
id="article-form-title"
onChange={[Function]}
onFocus={[Function]}
onInput={[Function]}
placeholder="Write your post content here..."
onKeyDown={[Function]}
placeholder="New post title here..."
ref={[Function]}
style={
Object {
"height": 0,
}
}
type="text"
value=""
/>
</div>
<div
class="crayons-article-form__tagsfield"
>
<div
class="crayons-article-form__tagswrapper"
>
<input
autoComplete="off"
class="crayons-textfield crayons-textfield--ghost ff-accent crayons-article-form__tags"
id="tag-input"
name="listing[tag_list]"
onBlur={[Function]}
onFocus={[Function]}
onInput={[Function]}
onKeyDown={[Function]}
placeholder="Add up to 4 tags..."
ref={[Function]}
type="text"
value=""
/>
</div>
</div>
</div>
<div
class="crayons-article-form__main__aside"
class="crayons-article-form__body"
>
<div
class="sticky"
class="crayons-article-form__toolbar false"
>
<div
class="flex items-center"
>
<button
class="crayons-btn crayons-btn--ghost crayons-btn--icon-left mr-2 fw-normal"
disabled={false}
tabIndex="-1"
type="button"
>
<svg
aria-labelledby="a17qec5pfhrwzk9w4kg0tp62v27qqu9t"
class="crayons-icon"
height="24"
role="img"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<title
id="a17qec5pfhrwzk9w4kg0tp62v27qqu9t"
>
Upload image
</title>
<path
d="M20 5H4v14l9.292-9.294a1 1 0 011.414 0L20 15.01V5zM2 3.993A1 1 0 012.992 3h18.016c.548 0 .992.445.992.993v16.014a1 1 0 01-.992.993H2.992A.993.993 0 012 20.007V3.993zM8 11a2 2 0 110-4 2 2 0 010 4z"
/>
</svg>
Upload image
<input
accept="image/*"
class="w-100 h-100 absolute left-0 right-0 top-0 bottom-0 overflow-hidden opacity-0 cursor-pointer"
data-max-file-size-mb="25"
id="image-upload-field"
multiple={true}
onChange={[Function]}
tabIndex="-1"
type="file"
/>
</button>
</div>
</div>
<textarea
class="crayons-textfield crayons-textfield--ghost crayons-article-form__body__field"
id="article_body_markdown"
name="body_markdown"
onChange={[Function]}
onFocus={[Function]}
onInput={[Function]}
placeholder="Write your post content here..."
ref={[Function]}
style={
Object {
"top": null,
"height": 0,
}
}
value=""
/>
</div>
</div>
<div
class="crayons-article-form__aside"
>
<div
class="sticky"
style={
Object {
"top": null,
}
}
/>
</div>
<div
class="crayons-article-form__footer"
>

View file

@ -297,37 +297,35 @@ export default class ArticleForm extends Component {
onToggle={this.handleOrgIdChange}
/>
<div className="crayons-article-form__main">
{previewShowing ? (
<Preview
previewResponse={previewResponse}
articleState={this.state}
errors={errors}
/>
) : (
<Form
titleDefaultValue={title}
titleOnChange={linkState(this, 'title')}
tagsDefaultValue={tagList}
tagsOnInput={linkState(this, 'tagList')}
bodyDefaultValue={bodyMarkdown}
bodyOnChange={linkState(this, 'bodyMarkdown')}
bodyHasFocus={false}
version={version}
mainImage={mainImage}
onMainImageUrlChange={this.handleMainImageUrlChange}
errors={errors}
switchHelpContext={this.switchHelpContext}
/>
)}
<Help
previewShowing={previewShowing}
helpFor={helpFor}
helpPosition={helpPosition}
version={version}
{previewShowing ? (
<Preview
previewResponse={previewResponse}
articleState={this.state}
errors={errors}
/>
</div>
) : (
<Form
titleDefaultValue={title}
titleOnChange={linkState(this, 'title')}
tagsDefaultValue={tagList}
tagsOnInput={linkState(this, 'tagList')}
bodyDefaultValue={bodyMarkdown}
bodyOnChange={linkState(this, 'bodyMarkdown')}
bodyHasFocus={false}
version={version}
mainImage={mainImage}
onMainImageUrlChange={this.handleMainImageUrlChange}
errors={errors}
switchHelpContext={this.switchHelpContext}
/>
)}
<Help
previewShowing={previewShowing}
helpFor={helpFor}
helpPosition={helpPosition}
version={version}
/>
<EditorActions
published={published}

View file

@ -19,7 +19,7 @@ export const Form = ({
errors,
}) => {
return (
<div className="crayons-article-form__main__content crayons-card">
<div className="crayons-article-form__content crayons-card">
{errors && <ErrorList errors={errors} />}
{version === 'v2' && (

View file

@ -6,7 +6,7 @@ import { PageTitle } from './PageTitle';
export const Header = ({onPreview, previewShowing, organizations, organizationId, onToggle}) => {
return (
<div className="crayons-article-form__header crayons-layout">
<div className="crayons-article-form__header">
<a href="/" className="crayons-article-form__logo" aria-label="Home">
<svg
xmlns="http://www.w3.org/2000/svg"

View file

@ -170,7 +170,7 @@ export class Help extends Component {
} = this.state;
return (
<div className="crayons-article-form__main__aside">
<div className="crayons-article-form__aside">
{!previewShowing && (
<div
className="sticky"

View file

@ -5,11 +5,11 @@ import { OrganizationPicker } from '../../organization/OrganizationPicker';
export const PageTitle = ({organizations, organizationId, onToggle}) => {
return (
<div className="crayons-field__label flex items-center flex-1">
<span className="hidden s:inline-block whitespace-nowrap">
<span className="hidden s:inline-block mr-2 whitespace-nowrap">
Write a new post
</span>
{organizations && organizations.length > 0 && (
<div className="mx-2">
<div>
<OrganizationPicker
name="article[organization_id]"
id="article_publish_under_org"

View file

@ -61,7 +61,7 @@ const previewResponsePropTypes = PropTypes.shape({
export const Preview = ({ previewResponse, articleState, errors }) => {
return (
<div className="crayons-article-form__main__content crayons-card">
<div className="crayons-article-form__content crayons-card">
<article className="crayons-article">
{titleArea(previewResponse, articleState, errors)}
<div

View file

@ -27,7 +27,7 @@ describe('<Help />', () => {
/>,
);
expect(
container.find('.crayons-article-form__main__aside').text().length,
container.find('.crayons-article-form__aside').text().length,
).toEqual(0);
});
@ -41,7 +41,7 @@ describe('<Help />', () => {
/>,
);
expect(
container.find('.crayons-article-form__main__aside').text().length,
container.find('.crayons-article-form__aside').text().length,
).toBeGreaterThan(0);
});
@ -55,7 +55,7 @@ describe('<Help />', () => {
/>,
);
expect(
container.find('.crayons-article-form__main__aside').text().length,
container.find('.crayons-article-form__aside').text().length,
).toBeGreaterThan(0);
});
@ -69,7 +69,7 @@ describe('<Help />', () => {
/>,
);
expect(
container.find('.crayons-article-form__main__aside').text().length,
container.find('.crayons-article-form__aside').text().length,
).toBeGreaterThan(0);
expect(container.find('.spec__basic-editor-help').exists()).toEqual(true);
expect(container.find('.spec__format-help').exists()).toEqual(true);
@ -89,7 +89,7 @@ describe('<Help />', () => {
/>,
);
expect(
container.find('.crayons-article-form__main__aside').text().length,
container.find('.crayons-article-form__aside').text().length,
).toBeGreaterThan(0);
expect(container.find('.spec__title-help').exists()).toEqual(true);
expect(container.find('.spec__format-help').exists()).toEqual(false);
@ -107,7 +107,7 @@ describe('<Help />', () => {
/>,
);
expect(
container2.find('.crayons-article-form__main__aside').text().length,
container2.find('.crayons-article-form__aside').text().length,
).toBeGreaterThan(0);
expect(container2.find('.spec__format-help').exists()).toEqual(true);
expect(container2.find('.spec__basic-editor-help').exists()).toEqual(false);
@ -125,7 +125,7 @@ describe('<Help />', () => {
/>,
);
expect(
container3.find('.crayons-article-form__main__aside').text().length,
container3.find('.crayons-article-form__aside').text().length,
).toBeGreaterThan(0);
expect(container3.find('.spec__basic-tag-input-help').exists()).toEqual(
true,

View file

@ -2,7 +2,7 @@
exports[`<Form /> v1 renders properly 1`] = `
<div
class="crayons-article-form__main__content crayons-card"
class="crayons-article-form__content crayons-card"
>
<div
class="crayons-article-form__body"
@ -73,7 +73,7 @@ exports[`<Form /> v1 renders properly 1`] = `
exports[`<Form /> v2 renders properly 1`] = `
<div
class="crayons-article-form__main__content crayons-card"
class="crayons-article-form__content crayons-card"
>
<div>
<div

View file

@ -2,7 +2,7 @@
exports[`<Help /> renders properly 1`] = `
<div
class="crayons-article-form__main__aside"
class="crayons-article-form__aside"
>
<div
class="sticky"

View file

@ -2,7 +2,7 @@
exports[`<Preview /> renders properly 1`] = `
<div
class="crayons-article-form__main__content crayons-card"
class="crayons-article-form__content crayons-card"
>
<article
class="crayons-article"

View file

@ -13,10 +13,10 @@ export const TagsFollowed = ({ tags = [] }) => {
id={`sidebar-element-${tag.name}`}
>
<a
className="sidebar-nav-link sidebar-nav-link-tag"
className="crayons-link crayons-link--block spec__tag-link"
href={`/t/${tag.name}`}
>
<span className="sidebar-nav-tag-text">{`#${tag.name}`}</span>
{`#${tag.name}`}
</a>
</div>
))}

View file

@ -15,14 +15,10 @@ exports[`<TagsFollowed /> should render the tags followed when tags are passed i
id="sidebar-element-javascript"
>
<a
class="sidebar-nav-link sidebar-nav-link-tag"
class="crayons-link crayons-link--block spec__tag-link"
href="/t/javascript"
>
<span
class="sidebar-nav-tag-text"
>
#javascript
</span>
#javascript
</a>
</div>
<div
@ -30,14 +26,10 @@ exports[`<TagsFollowed /> should render the tags followed when tags are passed i
id="sidebar-element-webdev"
>
<a
class="sidebar-nav-link sidebar-nav-link-tag"
class="crayons-link crayons-link--block spec__tag-link"
href="/t/webdev"
>
<span
class="sidebar-nav-tag-text"
>
#webdev
</span>
#webdev
</a>
</div>
<div
@ -45,14 +37,10 @@ exports[`<TagsFollowed /> should render the tags followed when tags are passed i
id="sidebar-element-react"
>
<a
class="sidebar-nav-link sidebar-nav-link-tag"
class="crayons-link crayons-link--block spec__tag-link"
href="/t/react"
>
<span
class="sidebar-nav-tag-text"
>
#react
</span>
#react
</a>
</div>
<div
@ -60,14 +48,10 @@ exports[`<TagsFollowed /> should render the tags followed when tags are passed i
id="sidebar-element-discuss"
>
<a
class="sidebar-nav-link sidebar-nav-link-tag"
class="crayons-link crayons-link--block spec__tag-link"
href="/t/discuss"
>
<span
class="sidebar-nav-tag-text"
>
#discuss
</span>
#discuss
</a>
</div>
<div
@ -75,14 +59,10 @@ exports[`<TagsFollowed /> should render the tags followed when tags are passed i
id="sidebar-element-productivity"
>
<a
class="sidebar-nav-link sidebar-nav-link-tag"
class="crayons-link crayons-link--block spec__tag-link"
href="/t/productivity"
>
<span
class="sidebar-nav-tag-text"
>
#productivity
</span>
#productivity
</a>
</div>
<div
@ -90,14 +70,10 @@ exports[`<TagsFollowed /> should render the tags followed when tags are passed i
id="sidebar-element-career"
>
<a
class="sidebar-nav-link sidebar-nav-link-tag"
class="crayons-link crayons-link--block spec__tag-link"
href="/t/career"
>
<span
class="sidebar-nav-tag-text"
>
#career
</span>
#career
</a>
</div>
<div
@ -105,14 +81,10 @@ exports[`<TagsFollowed /> should render the tags followed when tags are passed i
id="sidebar-element-node"
>
<a
class="sidebar-nav-link sidebar-nav-link-tag"
class="crayons-link crayons-link--block spec__tag-link"
href="/t/node"
>
<span
class="sidebar-nav-tag-text"
>
#node
</span>
#node
</a>
</div>
<div
@ -120,14 +92,10 @@ exports[`<TagsFollowed /> should render the tags followed when tags are passed i
id="sidebar-element-css"
>
<a
class="sidebar-nav-link sidebar-nav-link-tag"
class="crayons-link crayons-link--block spec__tag-link"
href="/t/css"
>
<span
class="sidebar-nav-tag-text"
>
#css
</span>
#css
</a>
</div>
<div
@ -135,14 +103,10 @@ exports[`<TagsFollowed /> should render the tags followed when tags are passed i
id="sidebar-element-html"
>
<a
class="sidebar-nav-link sidebar-nav-link-tag"
class="crayons-link crayons-link--block spec__tag-link"
href="/t/html"
>
<span
class="sidebar-nav-tag-text"
>
#html
</span>
#html
</a>
</div>
<div
@ -150,14 +114,10 @@ exports[`<TagsFollowed /> should render the tags followed when tags are passed i
id="sidebar-element-typescript"
>
<a
class="sidebar-nav-link sidebar-nav-link-tag"
class="crayons-link crayons-link--block spec__tag-link"
href="/t/typescript"
>
<span
class="sidebar-nav-tag-text"
>
#typescript
</span>
#typescript
</a>
</div>
<div
@ -165,14 +125,10 @@ exports[`<TagsFollowed /> should render the tags followed when tags are passed i
id="sidebar-element-opensource"
>
<a
class="sidebar-nav-link sidebar-nav-link-tag"
class="crayons-link crayons-link--block spec__tag-link"
href="/t/opensource"
>
<span
class="sidebar-nav-tag-text"
>
#opensource
</span>
#opensource
</a>
</div>
</div>

View file

@ -146,7 +146,7 @@ preact-render-spy (1 nodes)
class="onboarding-tags__button false"
style="background-color: #000000; color: #ffffff;"
>
+ Follow
Follow
</button>
</div>
</div>
@ -162,7 +162,7 @@ preact-render-spy (1 nodes)
class="onboarding-tags__button false"
style="background-color: #f7df1e; color: #000000;"
>
+ Follow
Follow
</button>
</div>
</div>
@ -178,7 +178,7 @@ preact-render-spy (1 nodes)
class="onboarding-tags__button false"
style="background-color: #2a2566; color: #ffffff;"
>
+ Follow
Follow
</button>
</div>
</div>

View file

@ -160,7 +160,7 @@ class FollowTags extends Component {
</span>
</span>
) : (
'+ Follow'
'Follow'
)}
</button>
</div>

View file

@ -55,7 +55,7 @@ class SidebarWidget extends Component {
const followBtn = document.getElementById(
`widget-list-item__follow-button-${updatedUser.username}`,
);
followBtn.innerText = updatedUser.following ? '+ FOLLOW' : '✓ FOLLOWING';
followBtn.innerText = updatedUser.following ? 'Follow' : 'Following';
const toggleFollowState = (newFollowState) => {
updatedUser.following = newFollowState === 'followed';

View file

@ -26,7 +26,7 @@ exports[`<SidebarUser /> renders properly 1`] = `
onClick={[Function]}
type="button"
>
+ FOLLOW
Follow
</button>
</div>
</div>

View file

@ -41,10 +41,10 @@ describe('<SidebarUser />', () => {
it('shows if the user is followed or not', () => {
expect(
renderedSideBar({ user: { following: true } }).contains('✓ FOLLOWING'),
renderedSideBar({ user: { following: true } }).contains('Following'),
).toBe(true);
expect(
renderedSideBar({ user: { following: false } }).contains('+ FOLLOW'),
renderedSideBar({ user: { following: false } }).contains('Follow'),
).toBe(true);
});
});

View file

@ -34,7 +34,7 @@ class SidebarUser extends Component {
onClick={this.onClick}
id={`widget-list-item__follow-button-${user.username}`}
>
{user.following ? '✓ FOLLOWING' : '+ FOLLOW'}
{user.following ? 'Following' : 'Follow'}
</button>
</div>
</div>

View file

@ -1,9 +1,9 @@
<div id="sidebar-wrapper-left" class="sidebar-wrapper sidebar-wrapper-left">
<div id="sidebar-wrapper-left" class="sidebar-wrapper sidebar-wrapper-left crayons-layout__sidebar-left">
<div class="sidebar-bg" id="sidebar-bg-left"></div>
<div class="side-bar">
<% cache(cache_key_heroku_slug("main-sidebar-nav--#{user_signed_in?}"), expires_in: 15.minutes) do %>
<%= render "articles/sidebar_nav" %>
<div class="<%= "hidden" if user_signed_in? %> px-2" id="sponsorship-widget">
<div class="<%= "hidden" if user_signed_in? %> px-1" id="sponsorship-widget">
<h4 class="flex align-center fs-s ff-accent fw-bold tt-uppercase mb-4">
Community Sponsors
<%= inline_svg_tag("twemoji/heart.svg", aria: true, class: "crayons-icon crayons-icon--default ml-1", title: "Love") %>
@ -23,10 +23,8 @@
<% cache("display-area-left-#{rand(5)}", expires_in: 5.minutes) do %>
<% @left_sidebar_ad = DisplayAd.for_display("sidebar_left") %>
<% if @left_sidebar_ad %>
<div class="widget" id="sponsorship-arbitrary-display-widget" data-id="<%= @left_sidebar_ad.id %>">
<div class="widget-body widget-body--sponsorship-arbitrary">
<%= @left_sidebar_ad.processed_html.html_safe %>
</div>
<div class="crayons-sponsorship-widget" id="sponsorship-arbitrary-display-widget" data-id="<%= @left_sidebar_ad.id %>">
<%= @left_sidebar_ad.processed_html.html_safe %>
</div>
<% end %>
<% end %>

View file

@ -1,12 +1,12 @@
<div id="sidebar-wrapper-right" class="sidebar-wrapper sidebar-wrapper-right">
<div id="sidebar-wrapper-right" class="sidebar-wrapper sidebar-wrapper-right crayons-layout__sidebar-right">
<div class="sidebar-bg" id="sidebar-bg-right"></div>
<div class="side-bar sidebar-additional showing" id="sidebar-additional">
<div class="side-bar sidebar-additional showing grid gap-4" id="sidebar-additional">
<% unless user_signed_in? %>
<div class="widget signin-cta-widget">
<header class="signin-cta-widget-header">
Join <%= community_name %>
<div class="crayons-card crayons-card--secondary signin-cta-widget">
<header class="crayons-card__header">
<h3 class="crayons-card__header__headline">Join <%= community_name %></h3>
</header>
<div class="widget-body">
<div class="p-4 grid gap-2">
<%= render partial: "shared/authentication/providers_sidebar" %>
</div>
</div>
@ -14,47 +14,50 @@
<% cache(cache_key_heroku_slug("main-article-right-sidebar-discussions-#{params[:timeframe]}"), expires_in: (params[:timeframe].blank? ? 120 : 360).seconds) do %>
<% @sidebar_ad = DisplayAd.for_display("sidebar_right") %>
<% if @sidebar_ad %>
<div class="widget">
<div class="widget-body" style="margin-top:-6px">
<%= @sidebar_ad.processed_html.html_safe %>
</div>
<div class="crayons-card crayons-card--secondary p-4 crayons-sponsorship-widget">
<%= @sidebar_ad.processed_html.html_safe %>
</div>
<% end %>
<%= render "articles/sidebar_campaign" if SiteConfig.campaign_sidebar_enabled? %>
<% if params[:timeframe].blank? && @listings.any? %>
<div class="widget" id="sidebar-listings-widget">
<header class="widget-header-listings">
<a href="/listings"><h4>Listings <span class="widget-listing-live-count"><%= @listings.size %></span></h4></a>
<button type="button" class="widget-minimize-button" id="sidebar-listings-widget-minimize-button">-</button>
<div class="crayons-card crayons-card--secondary">
<header class="crayons-card__header">
<h3 class="crayons-card__header__headline">Listings</h3>
<div class="crayons-card__actions">
<a href="/listings" class="crayons-link--branded fw-medium fs-s">See all</a>
</div>
</header>
<div class="widget-body widget-body-listings">
<div>
<% @listings.order("bumped_at DESC").limit(5).each do |listing| %>
<a class="widget-listing-link" href="<%= listing.path %>">
<span class="widget-listing-link-title"><%= listing.title %></span>
<span class="widget-listing-link-category"><%= listing.category %></span>
<a class="crayons-link crayons-link--contentful" href="<%= listing.path %>">
<div><%= listing.title %></div>
<div class="crayons-link__secondary"><%= listing.category %></div>
</a>
<% end %>
<a class="cta cta-button" href="/listings/new">CREATE A LISTING</a>
<a class="crayons-link crayons-link--branded block align-center p-3 fw-medium fs-s w-100" href="/listings/new">Create a Listing</a>
</div>
</div>
<% end %>
<% SiteConfig.sidebar_tags.each do |tag| %>
<div class="widget">
<header>
<a href="/t/<%= tag %>"><h4>#<%= tag %></h4></a>
<div class="crayons-card crayons-card--secondary">
<header class="crayons-card__header">
<h3 class="crayons-card__header__headline"><a href="/t/<%= tag %>">#<%= tag %></a></h3>
</header>
<div class="widget-body">
<div class="widget-link-list">
<% if tag == "help" %>
<% Article.active_help.limit(5).pluck(:path, :title, :comments_count, :created_at).each do |plucked_article| %>
<%= render "articles/widget_list_item", plucked_article: plucked_article, show_comment_count: true %>
<% end %>
<% else %>
<% Article.active_threads([tag], Timeframer.new(params[:timeframe]).datetime, 5).each do |plucked_article| %>
<%= render "articles/widget_list_item", plucked_article: plucked_article, show_comment_count: true %>
<% end %>
<div>
<% if tag == "help" %>
<% Article.active_help.limit(5).pluck(:path, :title, :comments_count, :created_at).each do |plucked_article| %>
<%= render "articles/widget_list_item", plucked_article: plucked_article, show_comment_count: true %>
<% end %>
</div>
<% else %>
<% Article.active_threads([tag], Timeframer.new(params[:timeframe]).datetime, 5).each do |plucked_article| %>
<%= render "articles/widget_list_item", plucked_article: plucked_article, show_comment_count: true %>
<% end %>
<% end %>
</div>
</div>
<% end %>

View file

@ -1,23 +1,21 @@
<div class="widget">
<div class="crayons-card crayons-card--secondary">
<% if SiteConfig.campaign_sidebar_image && SiteConfig.campaign_url %>
<a href="<%= SiteConfig.campaign_url %>">
<img src="<%= SiteConfig.campaign_sidebar_image %>" class="widget-image" style="height:116px;" />
<img src="<%= SiteConfig.campaign_sidebar_image %>" class="block w-100 h-auto radius-default" width="1000" height="420" />
</a>
<% elsif SiteConfig.campaign_sidebar_image %>
<img src="<%= SiteConfig.campaign_sidebar_image %>" class="widget-image" style="height:116px;" />
<img src="<%= SiteConfig.campaign_sidebar_image %>" class="block w-100 h-auto radius-default" width="1000" height="420" />
<% end %>
<header>
<h4>
<%= link_to "Stories (#{@campaign_articles_count})", "/t/#{SiteConfig.campaign_featured_tags.first}" %>
</h4>
<header class="crayons-card__header">
<h3 class="crayons-card__header__headline"><%= link_to "Stories (#{@campaign_articles_count})", "/t/#{SiteConfig.campaign_featured_tags.first}" %></h3>
</header>
<div class="widget-body">
<div class="widget-link-list">
<% @latest_campaign_articles.each do |plucked_article| %>
<%= render "articles/widget_list_item", plucked_article: plucked_article, show_comment_count: false %>
<% end %>
</div>
<div>
<% @latest_campaign_articles.each do |plucked_article| %>
<%= render "articles/widget_list_item", plucked_article: plucked_article, show_comment_count: false %>
<% end %>
</div>
<div class="grid gap-2 p-4">
<%= link_to "Share your project", "/new/#{SiteConfig.campaign_featured_tags.first}", class: "crayons-btn" %>
<%= link_to "See all posts", "/t/#{SiteConfig.campaign_featured_tags.first}", class: "crayons-btn crayons-btn--secondary" %>
</div>
<%= link_to "Share your project", "/new/#{SiteConfig.campaign_featured_tags.first}", class: "widget-button write" %>
<%= link_to "See all posts", "/t/#{SiteConfig.campaign_featured_tags.first}", class: "widget-button all-stories" %>
</div>

View file

@ -1,4 +1,4 @@
<nav class="sidebar-nav" id="sidebar-nav">
<nav class="mb-6" id="sidebar-nav">
<% if user_signed_in? %>
<a class="sidebar-profile" id="sidebar-profile" href="#">
<img src="" class="sidebar-profile--avatar" id="sidebar-profile--avatar" alt="" width="48" height="48">
@ -8,115 +8,107 @@
</div>
</a>
<% end %>
<% unless user_signed_in? %>
<a href="/enter" class="crayons-link crayons-link--block fw-bold">
<%= inline_svg_tag("twemoji/handshake.svg", aria: true, class: "crayons-icon crayons-icon--default", title: "Sign In/Up") %>
Sign In/Up
</a>
<% end %>
<% if false # Let's bring it when ready %>
<a href="/" class="crayons-link crayons-link--block">
<%= inline_svg_tag("twemoji/house.svg", aria: true, class: "crayons-icon crayons-icon--default", title: "Home") %>
Home
</a>
<% end %>
<% if user_signed_in? %>
<a href="<%= readinglist_path %>" class="crayons-link crayons-link--block">
<%= inline_svg_tag("twemoji/drawer.svg", aria: true, class: "crayons-icon crayons-icon--default", title: "Reading list") %>
Reading list <span id="reading-list-count" class="crayons-indicator"></span>
</a>
<% end %>
<a href="<%= listings_path %>" class="crayons-link crayons-link--block">
<%= inline_svg_tag("twemoji/listing.svg", aria: true, class: "crayons-icon crayons-icon--default", title: "Listings") %>
Listings
</a>
<a href="<%= pod_path %>" class="crayons-link crayons-link--block">
<%= inline_svg_tag("twemoji/mic.svg", aria: true, class: "crayons-icon crayons-icon--default", title: "Podcasts") %>
Podcasts
</a>
<a href="<%= videos_path %>" class="crayons-link crayons-link--block">
<%= inline_svg_tag("twemoji/camera.svg", aria: true, class: "crayons-icon crayons-icon--default", title: "Videos") %>
Videos
</a>
<a href="<%= tags_path %>" class="crayons-link crayons-link--block">
<%= inline_svg_tag("twemoji/tag.svg", aria: true, class: "crayons-icon crayons-icon--default", title: "Tags") %>
Tags
</a>
<div class="px-1">
<% unless user_signed_in? %>
<a href="/enter" class="crayons-link crayons-link--block fw-bold">
<%= inline_svg_tag("twemoji/handshake.svg", aria: true, class: "crayons-icon crayons-icon--default", title: "Sign In/Up") %>
Sign In/Up
</a>
<a href="javascript:void(0)" class="crayons-link crayons-link--secondary crayons-link--block crayons-link--block--indented fs-s" id="main-nav-more-trigger">More...</a>
<div class="hidden" id="main-nav-more">
<a href="/code-of-conduct" class="crayons-link crayons-link--block">
<%= inline_svg_tag("twemoji/thumb-up.svg", aria: true, class: "crayons-icon crayons-icon--default", title: "Code of Conduct") %>
Code of Conduct
</a>
<a href="/faq" class="crayons-link crayons-link--block">
<%= inline_svg_tag("twemoji/bulb.svg", aria: true, class: "crayons-icon crayons-icon--default", title: "FAQ") %>
FAQ
</a>
<% if SiteConfig.shop_url.present? %>
<a href="<%= SiteConfig.shop_url %>" class="crayons-link crayons-link--block">
<%= inline_svg_tag("twemoji/shopping.svg", aria: true, class: "crayons-icon crayons-icon--default", title: "Shop") %>
<%= community_name %> Shop
</a>
<% end %>
<% if false # Let's bring it when ready %>
<a href="/" class="crayons-link crayons-link--block">
<%= inline_svg_tag("twemoji/house.svg", aria: true, class: "crayons-icon crayons-icon--default", title: "Home") %>
Home
</a>
<% end %>
<% if user_signed_in? %>
<a href="<%= readinglist_path %>" class="crayons-link crayons-link--block">
<%= inline_svg_tag("twemoji/drawer.svg", aria: true, class: "crayons-icon crayons-icon--default", title: "Reading list") %>
Reading list <span id="reading-list-count" class="crayons-indicator"></span>
</a>
<% end %>
<a href="<%= listings_path %>" class="crayons-link crayons-link--block">
<%= inline_svg_tag("twemoji/listing.svg", aria: true, class: "crayons-icon crayons-icon--default", title: "Listings") %>
Listings
<a href="/sponsors" class="crayons-link crayons-link--block">
<%= inline_svg_tag("twemoji/heart.svg", aria: true, class: "crayons-icon crayons-icon--default", title: "Sponsors") %>
Sponsors
</a>
<a href="<%= pod_path %>" class="crayons-link crayons-link--block">
<%= inline_svg_tag("twemoji/mic.svg", aria: true, class: "crayons-icon crayons-icon--default", title: "Podcasts") %>
Podcasts
<a href="/about" class="crayons-link crayons-link--block">
<%= inline_svg_tag("rainbowdev.svg", aria: true, width: 24, height: 24, class: "crayons-icon crayons-icon--default p-1", title: "About") %>
About
</a>
<a href="<%= videos_path %>" class="crayons-link crayons-link--block">
<%= inline_svg_tag("twemoji/camera.svg", aria: true, class: "crayons-icon crayons-icon--default", title: "Videos") %>
Videos
<a href="/privacy" class="crayons-link crayons-link--block">
<%= inline_svg_tag("twemoji/smart.svg", aria: true, class: "crayons-icon crayons-icon--default", title: "Privacy policy") %>
Privacy policy
</a>
<a href="<%= tags_path %>" class="crayons-link crayons-link--block">
<%= inline_svg_tag("twemoji/tag.svg", aria: true, class: "crayons-icon crayons-icon--default", title: "Tags") %>
Tags
<a href="/terms" class="crayons-link crayons-link--block">
<%= inline_svg_tag("twemoji/look.svg", aria: true, class: "crayons-icon crayons-icon--default", title: "Terms of use") %>
Terms of use
</a>
<a href="javascript:void(0)" class="crayons-link crayons-link--secondary crayons-link--block crayons-link--block--indented fs-s" id="main-nav-more-trigger">More...</a>
<div class="hidden" id="main-nav-more">
<a href="/code-of-conduct" class="crayons-link crayons-link--block">
<%= inline_svg_tag("twemoji/thumb-up.svg", aria: true, class: "crayons-icon crayons-icon--default", title: "Code of Conduct") %>
Code of Conduct
</a>
<a href="/faq" class="crayons-link crayons-link--block">
<%= inline_svg_tag("twemoji/bulb.svg", aria: true, class: "crayons-icon crayons-icon--default", title: "FAQ") %>
FAQ
</a>
<% if SiteConfig.shop_url.present? %>
<a href="<%= SiteConfig.shop_url %>" class="crayons-link crayons-link--block">
<%= inline_svg_tag("twemoji/shopping.svg", aria: true, class: "crayons-icon crayons-icon--default", title: "Shop") %>
<%= community_name %> Shop
</a>
<% end %>
<a href="/sponsors" class="crayons-link crayons-link--block">
<%= inline_svg_tag("twemoji/heart.svg", aria: true, class: "crayons-icon crayons-icon--default", title: "Sponsors") %>
Sponsors
</a>
<a href="/about" class="crayons-link crayons-link--block">
<%= inline_svg_tag("rainbowdev.svg", aria: true, width: 24, height: 24, class: "crayons-icon crayons-icon--default p-1", title: "About") %>
About
</a>
<a href="/privacy" class="crayons-link crayons-link--block">
<%= inline_svg_tag("twemoji/smart.svg", aria: true, class: "crayons-icon crayons-icon--default", title: "Privacy policy") %>
Privacy policy
</a>
<a href="/terms" class="crayons-link crayons-link--block">
<%= inline_svg_tag("twemoji/look.svg", aria: true, class: "crayons-icon crayons-icon--default", title: "Terms of use") %>
Terms of use
</a>
<a href="/contact" class="crayons-link crayons-link--block">
<%= inline_svg_tag("twemoji/contact.svg", aria: true, class: "crayons-icon crayons-icon--default", title: "Contact") %>
Contact
</a>
<div class="flex justify-around p-4 mt-4 border-solid border-0 border-t-1 border-base-10">
<%= render partial: "layouts/social_media" %>
</div>
</div>
</div>
<div class="widget sidebar-nav-block sidebar-tag-block">
<div class="sidebar-nav-block-inner">
<% if user_signed_in? %>
<header>My Tags</header>
<div id="sidebar-nav-followed-tags" class="sidebar-nav-followed-tags"></div>
<% end %>
<div id="sidebar-nav-default-tags" class="sidebar-nav-default-tags <%= "showing" unless user_signed_in? %>">
<header id="tag-separator">
<% if user_signed_in? %>
Other Popular Tags
<% else %>
Design Your Experience
<% end %>
</header>
<% Tag.where(supported: true).order("hotness_score DESC").limit(30).pluck(:id, :name).each do |tag_array| %>
<div class="sidebar-nav-element" id="default-sidebar-element-<%= tag_array.second %>">
<a class="sidebar-nav-link sidebar-nav-link-tag" href="<%= tag_path(tag_array.second) %>">
<span class="sidebar-nav-tag-text">
#<%= tag_array.second %>
</span>
</a>
<a class="follow-action-button sidebar-nav-link-follow cta"
href="#" id="sidebar-nav-link-follow-<%= tag_array.second %>"
data-info='{"id":<%= tag_array.first %>,"className":"Tag"}'>
+ FOLLOW
</a>
</div>
<% end %>
</div>
<a href="/contact" class="crayons-link crayons-link--block">
<%= inline_svg_tag("twemoji/contact.svg", aria: true, class: "crayons-icon crayons-icon--default", title: "Contact") %>
Contact
</a>
<div class="flex justify-around p-4 mt-4 border-solid border-0 border-t-1 border-base-10">
<%= render partial: "layouts/social_media" %>
</div>
</div>
</nav>
<nav class="sidebar-tags-browser mb-6 overflow-y-auto scrolling-touch">
<% if user_signed_in? %>
<header class="fs-xs color-base-50 ff-accent fw-bold p-2">MY TAGS</header>
<div id="sidebar-nav-followed-tags" class="sidebar-nav-followed-tags"></div>
<% end %>
<div id="sidebar-nav-default-tags" class="sidebar-nav-default-tags <%= "showing" unless user_signed_in? %>">
<header id="tag-separator" class="fs-xs color-base-50 ff-accent fw-bold p-2">
<% if user_signed_in? %>
OTHER POPULAR TAGS
<% else %>
DESIGN YOUR EXPERIENCE
<% end %>
</header>
<% Tag.where(supported: true).order("hotness_score DESC").limit(30).pluck(:id, :name).each do |tag_array| %>
<div class="sidebar-nav-element" id="default-sidebar-element-<%= tag_array.second %>">
<a class="crayons-link crayons-link--block" href="<%= tag_path(tag_array.second) %>">
#<%= tag_array.second %>
</a>
<a class="follow-action-button sidebar-nav-link-follow crayons-btn crayons-btn--s crayons-btn--secondary_"
href="#" id="sidebar-nav-link-follow-<%= tag_array.second %>"
data-info='{"id":<%= tag_array.first %>,"className":"Tag"}'>
Follow
</a>
</div>
<% end %>
</nav>

View file

@ -23,9 +23,9 @@
<a href="/" class="crayons-article-form__logo" aria-label="<%= community_name %> Home"><%= logo_svg %></a>
<div class="crayons-field__label">
<span class="hidden s:inline-block">Write a new post</span>
<span class="hidden s:inline-block mr-2">Write a new post</span>
<% if organizations && organizations.size > 0 %>
<select name="article[organization_id]" id="article_publish_under_org" class="crayons-select w-auto ml-2 mt-0">
<select name="article[organization_id]" id="article_publish_under_org" class="crayons-select w-auto mt-0">
<%= options_for_select({ "Personal" => "" }.merge(organizations.pluck(:name, :id).to_h), article.organization_id || "") %>
</select>
<% end %>
@ -42,42 +42,41 @@
</div>
</div>
<div class="crayons-article-form__main">
<div class="crayons-card crayons-article-form__main__content">
<% if version == "v2" %>
<div>
<div class="crayons-article-form__cover" role="presentation">
<% if article.main_image.present? %>
<img src="<%= article.main_image %>" width="250" height="105" alt="Post cover" class="crayons-article-form__cover__image">
<% end %>
<button class="crayons-btn crayons-btn--outlined mr-2">
<label for="cover-image-input">
<% if article.main_image.present? %>Change<% else %>Add a cover image<% end %>
</label>
<input id="cover-image-input" type="file" accept="image/*" class="w-100 h-100 absolute left-0 right-0 top-0 bottom-0 overflow-hidden opacity-0 cursor-pointer" data-max-file-size-mb="25">
</button>
</div>
<div class="crayons-article-form__title">
<textarea class="crayons-textfield crayons-textfield--ghost fs-3xl s:fs-4xl l:fs-5xl fw-bold s:fw-heavy lh-tight" type="text" id="article-form-title" placeholder="New post title here..." autocomplete="off" style="height: 60px; "><%= article.title %></textarea>
</div>
<div class="crayons-article-form__tagsfield">
<input type="text" class="crayons-textfield crayons-textfield--ghost ff-accent" placeholder="Add up to 4 tags..." name="tags" value="<%= article.cached_tag_list %>" />
</div>
</div>
<% end %>
<div class="crayons-article-form__body">
<div class="crayons-article-form__toolbar">
<button class="crayons-btn crayons-btn--ghost crayons-btn--icon-left fw-normal" type="button">
<%= (inline_svg_tag("image.svg", aria: true, class: "crayons-icon", title: "Image") + "Upload image").delete!("\n").html_safe %>
<input type="file" id="image-upload-field" class="w-100 h-100 absolute left-0 right-0 top-0 bottom-0 overflow-hidden opacity-0 cursor-pointer" multiple accept="image/*" data-max-file-size-mb="25" />
<div class="crayons-card crayons-article-form__content">
<% if version == "v2" %>
<div>
<div class="crayons-article-form__cover" role="presentation">
<% if article.main_image.present? %>
<img src="<%= article.main_image %>" width="250" height="105" alt="Post cover" class="crayons-article-form__cover__image">
<% end %>
<button class="crayons-btn crayons-btn--outlined mr-2">
<label for="cover-image-input">
<% if article.main_image.present? %>Change<% else %>Add a cover image<% end %>
</label>
<input id="cover-image-input" type="file" accept="image/*" class="w-100 h-100 absolute left-0 right-0 top-0 bottom-0 overflow-hidden opacity-0 cursor-pointer" data-max-file-size-mb="25">
</button>
</div>
<textarea class="crayons-article-form__body__field crayons-textfield crayons-textfield--ghost" id="article_body_markdown" placeholder="Write your post content here..." name="body_markdown"><%= article.body_markdown %></textarea>
<div class="crayons-article-form__title">
<textarea class="crayons-textfield crayons-textfield--ghost fs-3xl s:fs-4xl l:fs-5xl fw-bold s:fw-heavy lh-tight" type="text" id="article-form-title" placeholder="New post title here..." autocomplete="off" style="height: 60px; "><%= article.title %></textarea>
</div>
<div class="crayons-article-form__tagsfield">
<input type="text" class="crayons-textfield crayons-textfield--ghost ff-accent" placeholder="Add up to 4 tags..." name="tags" value="<%= article.cached_tag_list %>" />
</div>
</div>
<% end %>
<div class="crayons-article-form__body">
<div class="crayons-article-form__toolbar">
<button class="crayons-btn crayons-btn--ghost crayons-btn--icon-left fw-normal" type="button">
<%= (inline_svg_tag("image.svg", aria: true, class: "crayons-icon", title: "Image") + "Upload image").delete!("\n").html_safe %>
<input type="file" id="image-upload-field" class="w-100 h-100 absolute left-0 right-0 top-0 bottom-0 overflow-hidden opacity-0 cursor-pointer" multiple accept="image/*" data-max-file-size-mb="25" />
</button>
</div>
<textarea class="crayons-article-form__body__field crayons-textfield crayons-textfield--ghost" id="article_body_markdown" placeholder="Write your post content here..." name="body_markdown"><%= article.body_markdown %></textarea>
</div>
<div class="crayons-article-form__main_aside"></div>
</div>
<div class="crayons-article-form__aside"></div>
<div class="crayons-article-form__footer">
<button class="crayons-btn mr-2" type="button">Publish</button>
<button class="crayons-btn crayons-btn--secondary mr-2" type="button">Save draft</button>

View file

@ -1,11 +1,11 @@
<a href="<%= plucked_article[0] %>" class="widget-link-list__item">
<a class="crayons-link crayons-link--contentful" href="<%= plucked_article[0] %>">
<%= plucked_article[1] %>
<% if show_comment_count %>
<div class="discuss-list-comment-count">
<div class="crayons-link__secondary">
<% if plucked_article[2] > 0 %>
<img src="<%= asset_path("comments-bubble.svg") %>" alt="Comments" /> <%= plucked_article[2] %>
Comments: <%= plucked_article[2] %>
<% else %>
<span class="discuss-list-comment-count discuss-list-comment-count-brand-new">fresh</span>
<span class="crayons-indicator crayons-indicator--accent">New</span>
<% end %>
</div>
<% end %>

View file

@ -27,7 +27,7 @@
<%= javascript_packs_with_chunks_tag "homePage", defer: true %>
<% cache(cache_key_heroku_slug("main-stories-index-#{params}-#{user_signed_in?}"), expires_in: 90.seconds) do %>
<div class="home" id="index-container"
<div class="crayons-layout crayons-layout--3-cols crayons-layout--3-cols--drop-right-left" id="index-container"
data-params="<%= params.merge(sort_by: "hotness_score", sort_direction: "desc").to_json(only: %i[tag username q sort_by sort_direction]) %>" data-which="<%= @list_of %>"
data-tag=""
data-feed="<%= params[:timeframe] || "base-feed" %>"
@ -35,11 +35,12 @@
<%= render "articles/sidebar" %>
<div class="articles-list" id="articles-list">
<%# BEGIN Feed menu bar %>
<div class="articles-list crayons-layout__content" id="articles-list">
<%= render(partial: "onboardings/task_card") if user_signed_in? %>
<header class="flex items-center p-2 m:p-0 m:pb-2" id="on-page-nav-controls">
<button type="button" class="crayons-btn crayons-btn--ghost crayons-btn--icon mr-2 inline-block l:hidden" id="on-page-nav-butt-left" aria-label="nav-button-left">
<button type="button" class="crayons-btn crayons-btn--ghost crayons-btn--icon mr-2 inline-block m:hidden" id="on-page-nav-butt-left" aria-label="nav-button-left">
<%= inline_svg_tag("stack.svg", aria: true, width: 24, height: 24, class: "crayons-icon", title: "Left sidebar") %>
</button>
<div class="flex-1 flex items-center justify-between">

View file

@ -1,7 +1,7 @@
<% authentication_enabled_providers.each do |provider| %>
<a
href="<%= provider.sign_in_path(state: "navbar_basic") %>"
class="cta cta-button login-cta-button"
class="crayons-btn crayons-btn--l"
data-no-instant>
Sign In With <%= provider.official_name %>
</a>

View file

@ -19,41 +19,50 @@
</div>
<% end %>
<main class="crayons-layout crayons-layout--max-l crayons-layout--default">
<div class="crayons-layout__sidebar">
<nav>
<header class="crayons-layout crayons-layout--limited crayons-layout--1-col p-4">
<% if @tab == "organization" && @organizations.present? %>
<h1 class="fs-2xl s:fs-3xl">Settings for
<span class="organization-dropdown">
<select id="organization-dropdown-select" onchange="window.location.href=this.value">
<% options = @organizations.pluck(:slug, :id).each do |arr| %>
<% arr[0] = "@#{arr[0]}" %>
<% arr[1] = "/settings/organization/#{arr[1]}" %>
<% end.to_h.merge("New Organization" => "/settings/organization/new") %>
<%= options_for_select(options, "/settings/organization/#{params[:org_id]}") %>
<%# For example: %>
<%# <option value="/settings/organization/1>@devteam</option> %>
<%# <option value="/settings/organization/new" selected>New Organization</option> %>
</select>
</span>
</h1>
<% else %>
<h1 class="fs-2xl s:fs-3xl">
Settings for <a href="<%= user_url(@user) || '#' %>">@<%= @user.username.truncate(User::USERNAME_MAX_LENGTH) %></a>
</h1>
<% end %>
</header>
<main class="crayons-layout crayons-layout--2-cols crayons-layout--limited">
<div class="crayons-layout__left-sidebar">
<nav class="hidden m:block">
<% @tab_list.each do |possible_tab| %>
<a class="crayons-link crayons-link--block <% if @tab == possible_tab.downcase.tr(' ', '-') %>crayons-link--current<% end %>" href="/settings/<%= possible_tab.downcase.tr(" ", "-") %>">
<%= possible_tab %>
</a>
<% end %>
</nav>
<div class="m:hidden p-2 pt-0">
<select id="mobile-page-selector" class="crayons-select">
<% @tab_list.each do |possible_tab| %>
<option value="/settings/<%= possible_tab.downcase.tr(" ", "-") %>" <% if @tab == possible_tab.downcase.tr(' ', '-') %>selected<% end %>>
<%= possible_tab %>
</option>
<% end %>
</select>
</div>
</div>
<div class="crayons-layout__content">
<header class="crayons-layout__page-header px-3 s:px-0 mb-4">
<% if @tab == "organization" && @organizations.present? %>
<h1 class="fs-xl s:fs-3xl">Settings for
<span class="organization-dropdown">
<select id="organization-dropdown-select" onchange="window.location.href=this.value">
<% options = @organizations.pluck(:slug, :id).each do |arr| %>
<% arr[0] = "@#{arr[0]}" %>
<% arr[1] = "/settings/organization/#{arr[1]}" %>
<% end.to_h.merge("New Organization" => "/settings/organization/new") %>
<%= options_for_select(options, "/settings/organization/#{params[:org_id]}") %>
<%# For example: %>
<%# <option value="/settings/organization/1>@devteam</option> %>
<%# <option value="/settings/organization/new" selected>New Organization</option> %>
</select>
</span>
</h1>
<% else %>
<h1 class="fs-xl s:fs-3xl">
Settings for <a href="<%= user_url(@user) || '#' %>">@<%= @user.username.truncate(User::USERNAME_MAX_LENGTH) %></a>
</h1>
<% end %>
</header>
<% if current_user.email.blank? %>
<div class="crayons-notice crayons-notice--warning mb-6">
<h3 class="mb-2">Confirm your email to complete your profile.</h3>

View file

@ -21,7 +21,7 @@ RSpec.describe "User visits articles by tag", type: :system do
end
it "shows the follow button", js: true do
within("h1") { expect(page).to have_button("+ FOLLOW") }
within("h1") { expect(page).to have_button("Follow") }
end
it "shows time buttons" do
@ -76,7 +76,7 @@ RSpec.describe "User visits articles by tag", type: :system do
# TODO: Add Percy snapshot?
wait_for_javascript
within("h1") { expect(page).to have_button("✓ FOLLOWING") }
within("h1") { expect(page).to have_button("Following") }
end
end
end

View file

@ -18,8 +18,8 @@ RSpec.describe "Followers Dashboard", type: :system, js: true do
user.follow(followed_user)
visit "/dashboard/user_followers"
expect(JSON.parse(find_link("✓ FOLLOWING")["data-info"])["id"]).to eq(followed_user.id)
expect(JSON.parse(find_link("+ FOLLOW BACK")["data-info"])["id"]).to eq(following_user.id)
expect(JSON.parse(find_link("Following")["data-info"])["id"]).to eq(followed_user.id)
expect(JSON.parse(find_link("Follow back")["data-info"])["id"]).to eq(following_user.id)
end
end
end

View file

@ -26,7 +26,7 @@ RSpec.describe "User visits a homepage", type: :system do
end
end
expect(page).to have_text("Design Your Experience")
expect(page).to have_text("DESIGN YOUR EXPERIENCE")
end
describe "link tags" do
@ -52,7 +52,7 @@ RSpec.describe "User visits a homepage", type: :system do
visit "/"
within("#sidebar-nav-default-tags") do
expect(page).to have_text("Follow tags to improve your feed")
expect(page).to have_text("FOLLOW TAGS TO IMPROVE YOUR FEED")
end
end
@ -66,7 +66,7 @@ RSpec.describe "User visits a homepage", type: :system do
end
it "shows the followed tags", js: true do
expect(page).to have_text("My Tags")
expect(page).to have_text("MY TAGS")
# Need to ensure the user data is loaded before doing any checks
find("body")["data-user"]
@ -81,12 +81,12 @@ RSpec.describe "User visits a homepage", type: :system do
find("body")["data-user"]
within("#sidebar-nav-followed-tags") do
expect(all(".sidebar-nav-tag-text").map(&:text)).to eq(%w[#javascript #go #ruby])
expect(all(".spec__tag-link").map(&:text)).to eq(%w[#javascript #go #ruby])
end
end
it "shows other tags", js: true do
expect(page).to have_text("Other Popular Tags")
expect(page).to have_text("OTHER POPULAR TAGS")
within("#sidebar-nav-default-tags") do
expect(page).to have_link("#webdev", href: "/t/webdev")
expect(page).not_to have_link("#ruby", href: "/t/ruby")

View file

@ -50,8 +50,8 @@ RSpec.describe "Notifications page", type: :system, js: true do
Notification.send_new_follower_notification_without_delay(follow, "Published")
visit "/notifications"
expect(page).to have_css("div.single-notification")
click_button("+ FOLLOW BACK")
expect(page).to have_text("FOLLOWING")
click_button("Follow back")
expect(page).to have_text("Following")
end
context "when user is trusted" do

View file

@ -15,7 +15,7 @@ RSpec.describe "Organization index", type: :system do
it "shows the header", js: true do
within("h1") { expect(page).to have_content(organization.name) }
within("div.profile-details") do
expect(page).to have_button("+ FOLLOW")
expect(page).to have_button("Follow")
end
end
@ -57,7 +57,7 @@ RSpec.describe "Organization index", type: :system do
visit "/#{organization.slug}"
within(".profile-details") do
expect(page).to have_button("✓ FOLLOWING")
expect(page).to have_button("Following")
end
end
end

View file

@ -29,6 +29,6 @@ RSpec.describe "Display users search spec", type: :system, js: true, elasticsear
expect(page).to have_content(found_user.name)
expect(find("span.crayons-story__flare-tag").text).to have_content("person")
expect(find(:xpath, "//img[@alt='#{found_user.username} profile']")["src"]).to include(found_user.profile_image_90)
expect(JSON.parse(find_button("+ FOLLOW")["data-info"])["id"]).to eq(found_user.id)
expect(JSON.parse(find_button("Follow")["data-info"])["id"]).to eq(found_user.id)
end
end

View file

@ -18,9 +18,9 @@ RSpec.describe "User searches users", type: :system do
stub_request(:post, "http://www.google-analytics.com/collect")
visit "/search?q=&filters=class_name:User"
expect(JSON.parse(find_button("EDIT PROFILE")["data-info"])["id"]).to eq(current_user.id)
expect(JSON.parse(find_button("FOLLOWING")["data-info"])["id"]).to eq(followed_user.id)
expect(JSON.parse(find_button("+ FOLLOW")["data-info"])["id"]).to eq(not_followed_user.id)
expect(JSON.parse(find_button("+ FOLLOW BACK")["data-info"])["id"]).to eq(follow_back_user.id)
expect(JSON.parse(find_button("Edit profile")["data-info"])["id"]).to eq(current_user.id)
expect(JSON.parse(find_button("Following")["data-info"])["id"]).to eq(followed_user.id)
expect(JSON.parse(find_button("Follow")["data-info"])["id"]).to eq(not_followed_user.id)
expect(JSON.parse(find_button("Follow back")["data-info"])["id"]).to eq(follow_back_user.id)
end
end

View file

@ -16,7 +16,7 @@ RSpec.describe "User index", type: :system do
within("h1") { expect(page).to have_content(user.name) }
within(".profile-details") do
expect(page).to have_button("+ FOLLOW")
expect(page).to have_button("Follow")
end
end
@ -90,7 +90,7 @@ RSpec.describe "User index", type: :system do
it "shows the header", js: true do
within("h1") { expect(page).to have_content(user.name) }
within(".profile-details") do
expect(page).to have_button("EDIT PROFILE")
expect(page).to have_button("Edit profile")
end
end