Improve onboarding UI and UX (P1) (#6901)
* Improve onboarding UI and UX (P1) - Introduce Crayons variables - Remove unnecessary CSS files to have just one CSS file * Add new onboarding tests * Update onboarding yarn test to reflect updated class names
This commit is contained in:
parent
ec371b4624
commit
b6fd02b70f
12 changed files with 1117 additions and 876 deletions
|
|
@ -1,45 +0,0 @@
|
|||
@import 'variables';
|
||||
|
||||
#onboarding-container {
|
||||
min-height: calc(100vh - 350px);
|
||||
}
|
||||
|
||||
.onboarding-container {
|
||||
max-width: 800px;
|
||||
margin: 0 auto;
|
||||
|
||||
.next-button {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.next-button,
|
||||
.back-button {
|
||||
padding: 4px 20px;
|
||||
border-radius: 100px;
|
||||
margin-right: 5px;
|
||||
font-size: 14px;
|
||||
margin-top: 6px;
|
||||
display: inline-block;
|
||||
color: #0a0a0a;
|
||||
}
|
||||
|
||||
.next-button {
|
||||
background: #66e2d5;
|
||||
border: 2px solid transparent;
|
||||
}
|
||||
|
||||
.back-button {
|
||||
background: white;
|
||||
border: 2px solid black;
|
||||
}
|
||||
|
||||
label,
|
||||
textarea,
|
||||
input {
|
||||
display: block;
|
||||
}
|
||||
|
||||
input[type='checkbox'] {
|
||||
display: inline;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,440 +1,548 @@
|
|||
@import 'variables';
|
||||
@import 'mixins';
|
||||
@import 'components/buttons';
|
||||
@import 'components/modals';
|
||||
@import 'components/forms';
|
||||
@import 'config/import';
|
||||
|
||||
#onboarding-container {
|
||||
min-height: calc(100vh - 350px);
|
||||
}
|
||||
|
||||
.pages-onboarding {
|
||||
min-height: initial;
|
||||
}
|
||||
|
||||
.onboarding-body {
|
||||
background-color: var(--body-bg);
|
||||
position: fixed;
|
||||
margin-top: 50px;
|
||||
bottom: 0;
|
||||
height: 100vh;
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
line-height: 200%;
|
||||
z-index: 11;
|
||||
margin: 0;
|
||||
background-image: url('/assets/onboarding-background-white.png');
|
||||
-webkit-background-size: cover;
|
||||
-moz-background-size: cover;
|
||||
-o-background-size: cover;
|
||||
background-size: cover;
|
||||
/* Center the image */
|
||||
background-position: center;
|
||||
/* Do not repeat the image */
|
||||
background-repeat: no-repeat;
|
||||
// modal box card
|
||||
.onboarding-main {
|
||||
@extend .crayons-modal;
|
||||
@extend .crayons-modal--l;
|
||||
@extend .crayons-modal--padding-0;
|
||||
border: none;
|
||||
z-index: 1;
|
||||
|
||||
@media screen and (min-width: 600px) {
|
||||
border-width: 2px;
|
||||
min-height: auto;
|
||||
}
|
||||
|
||||
a {
|
||||
color: var(--link-brand-color);
|
||||
}
|
||||
}
|
||||
|
||||
.sticker-logo {
|
||||
height: 80px;
|
||||
width: 80px;
|
||||
transform: rotate(-5deg);
|
||||
padding: 10px;
|
||||
vertical-align: middle;
|
||||
top: -10px;
|
||||
padding-top: 5px;
|
||||
}
|
||||
// modal inner content spacing
|
||||
.onboarding-content {
|
||||
box-sizing: border-box;
|
||||
flex: 1 0 auto;
|
||||
padding: $su-4;
|
||||
width: 100%;
|
||||
|
||||
.onboarding-main {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 800px;
|
||||
height: 466px;
|
||||
@include themeable(background-color, theme-container-background, $white);
|
||||
border: 8px solid #6b55c9;
|
||||
@include themeable(border-color, theme-container-border, #6b55c9);
|
||||
padding: 30px;
|
||||
border-radius: 3px;
|
||||
z-index: 1;
|
||||
font-size: 20px;
|
||||
box-shadow: 0 0 8px 2px rgba(0, 0, 0, 0.3), 8px 0px 13px rgba(0, 0, 0, 0.21);
|
||||
align-items: center;
|
||||
@media screen and (min-width: $breakpoint-s) {
|
||||
justify-content: center;
|
||||
padding: $su-7 $su-8 $su-8;
|
||||
}
|
||||
}
|
||||
|
||||
.onboarding-content {
|
||||
flex: 1 0 auto;
|
||||
width: 100%;
|
||||
margin-top: 5px;
|
||||
// window background
|
||||
.onboarding-body {
|
||||
-moz-background-size: cover;
|
||||
-o-background-size: cover;
|
||||
-webkit-background-size: cover;
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
background-size: cover;
|
||||
display: flex;
|
||||
height: 100vh;
|
||||
justify-content: start;
|
||||
line-height: 200%;
|
||||
margin: 0;
|
||||
overflow-y: scroll;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
|
||||
h1 {
|
||||
margin-top: 15px;
|
||||
line-height: 1.1em;
|
||||
}
|
||||
|
||||
@media screen and (min-width: 800px) {
|
||||
height: 440px;
|
||||
}
|
||||
}
|
||||
|
||||
.onboarding-navigation {
|
||||
align-self: flex-end;
|
||||
flex-shrink: 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.background-image {
|
||||
z-index: -1;
|
||||
position: absolute;
|
||||
top: 60px;
|
||||
left: 0px;
|
||||
}
|
||||
|
||||
h1 {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
h2 {
|
||||
margin-top: 20px;
|
||||
font-size: 15px;
|
||||
|
||||
@media screen and (min-width: 600px) {
|
||||
font-size: 26px;
|
||||
}
|
||||
}
|
||||
|
||||
p {
|
||||
line-height: 1.25em;
|
||||
}
|
||||
|
||||
button {
|
||||
width: 130px;
|
||||
padding: 6px 0px;
|
||||
height: auto;
|
||||
margin: 11px 20px;
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
border-radius: 3px;
|
||||
border: 2px solid #0a0a0a;
|
||||
@include themeable(border-color, theme-color, #0a0a0a);
|
||||
@include themeable(color, theme-color, #0a0a0a);
|
||||
@include themeable(
|
||||
background-color,
|
||||
theme-container-accent-background,
|
||||
$light-gray
|
||||
);
|
||||
font-family: 'HelveticaNeue-CondensedBold', 'HelveticaNeueBoldCondensed',
|
||||
'HelveticaNeue-Bold-Condensed', 'Helvetica Neue Bold Condensed',
|
||||
'HelveticaNeueBold', 'HelveticaNeue-Bold', 'Helvetica Neue Bold',
|
||||
'HelveticaNeue', 'Helvetica Neue', 'TeXGyreHerosCnBold', 'Helvetica',
|
||||
'Tahoma', 'Geneva', 'Arial Narrow', 'Arial', sans-serif;
|
||||
-webkit-appearance: none;
|
||||
font-stretch: condensed;
|
||||
font-size: 26px;
|
||||
}
|
||||
|
||||
.next-button {
|
||||
color: var(--button-primary-color);
|
||||
background: var(--button-primary-bg);
|
||||
float: right;
|
||||
}
|
||||
|
||||
.about {
|
||||
width: 100%;
|
||||
|
||||
label,
|
||||
input,
|
||||
textarea {
|
||||
display: block;
|
||||
width: 95%;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
input,
|
||||
textarea {
|
||||
padding: 12px;
|
||||
font-size: 19px;
|
||||
text-emphasis: bold;
|
||||
border: 1px solid #dee6e9;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
textarea {
|
||||
height: 120px;
|
||||
}
|
||||
}
|
||||
|
||||
.checkbox-slide {
|
||||
label {
|
||||
display: block;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
input[type='checkbox'] {
|
||||
-webkit-appearance: none;
|
||||
width: 19px;
|
||||
height: 19px;
|
||||
background: transparent;
|
||||
border-radius: 5px;
|
||||
border: 2px solid #555;
|
||||
vertical-align: middle;
|
||||
margin: 8px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
input[type='checkbox']:checked {
|
||||
background: var(--link-brand-color);
|
||||
}
|
||||
}
|
||||
|
||||
.warning-message {
|
||||
background-color: red;
|
||||
opacity: 0.7;
|
||||
padding: 10px;
|
||||
width: 100%;
|
||||
border-radius: 3px;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.scroll {
|
||||
height: 365px;
|
||||
overflow: auto;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
border-bottom: 1px solid $light-medium-gray;
|
||||
}
|
||||
|
||||
.tag {
|
||||
padding: 44px 6px 46px;
|
||||
font-size: 20px;
|
||||
margin: 5px;
|
||||
border-radius: 3px;
|
||||
font-weight: bold;
|
||||
border: none;
|
||||
outline: none;
|
||||
@media screen and (min-width: 600px) {
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
text-overflow: ellipsis;
|
||||
width: 100%;
|
||||
opacity: 0.8;
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto,
|
||||
Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji',
|
||||
'Segoe UI Symbol';
|
||||
|
||||
@media screen and (min-width: 600px) {
|
||||
width: 255px;
|
||||
}
|
||||
|
||||
&.tag-selected {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.onboarding-tag-follow-indicator {
|
||||
position: absolute;
|
||||
bottom: 22px;
|
||||
left: 0px;
|
||||
right: 0px;
|
||||
text-align: center;
|
||||
font-size: 0.66em;
|
||||
}
|
||||
background-image: url('/assets/onboarding-background-white.png');
|
||||
}
|
||||
|
||||
.select-all-button-wrapper {
|
||||
width: 100%;
|
||||
|
||||
button {
|
||||
width: 300px;
|
||||
line-height: 1em;
|
||||
text-align: left;
|
||||
padding-left: 15px;
|
||||
}
|
||||
}
|
||||
|
||||
.user {
|
||||
width: calc(100% - 40px);
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto,
|
||||
Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji',
|
||||
'Segoe UI Symbol';
|
||||
font-size: 15px;
|
||||
padding: 5px;
|
||||
border-radius: 3px;
|
||||
text-align: center;
|
||||
margin-right: 5px;
|
||||
position: relative;
|
||||
color: $black;
|
||||
|
||||
.onboarding-user-follow-status {
|
||||
position: absolute;
|
||||
color: #32a99c;
|
||||
right: 8px;
|
||||
top: 5px;
|
||||
font-size: 0.88em;
|
||||
}
|
||||
|
||||
span {
|
||||
display: block;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
p {
|
||||
font-weight: 400;
|
||||
height: 55px;
|
||||
}
|
||||
|
||||
@media screen and (min-width: 600px) {
|
||||
width: 365px;
|
||||
}
|
||||
|
||||
img {
|
||||
height: 80px;
|
||||
width: 80px;
|
||||
border-radius: 50%;
|
||||
padding: 5px;
|
||||
margin: 10px auto;
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
.user:active {
|
||||
background-color: red;
|
||||
}
|
||||
|
||||
.badge-image {
|
||||
&:before {
|
||||
display: block;
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
background: rgba(0, 0, 0, 0.65);
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.onboarding-what-next {
|
||||
// modal navigation
|
||||
.onboarding-navigation {
|
||||
align-self: flex-end;
|
||||
flex-shrink: 0;
|
||||
width: 100%;
|
||||
border-bottom: 2px solid var(--box-darker);
|
||||
|
||||
.navigation-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 250px;
|
||||
overflow: auto;
|
||||
|
||||
@media screen and (min-width: 600px) {
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
a {
|
||||
background: #d9e7ff;
|
||||
padding: 15px 4px 0px 12px;
|
||||
height: 140px;
|
||||
margin: 4px auto;
|
||||
border-radius: 3px;
|
||||
width: 350px;
|
||||
display: block;
|
||||
line-height: 1.2em;
|
||||
font-weight: bold;
|
||||
position: relative;
|
||||
text-align: center;
|
||||
|
||||
@media screen and (min-width: 600px) {
|
||||
height: 220px;
|
||||
margin: 4px 4px;
|
||||
text-align: left;
|
||||
padding: 20px 4px 0px 12px;
|
||||
}
|
||||
|
||||
.whatnext-emoji {
|
||||
display: none;
|
||||
text-align: center;
|
||||
position: absolute;
|
||||
bottom: 22px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
font-size: 50px;
|
||||
|
||||
@media screen and (min-width: 600px) {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.onboarding-previous-location {
|
||||
text-align: center;
|
||||
margin-top: 10px;
|
||||
font-weight: bold;
|
||||
display: none;
|
||||
|
||||
@media screen and (min-width: 600px) {
|
||||
display: block;
|
||||
}
|
||||
|
||||
code {
|
||||
font-size: 0.6em;
|
||||
margin-top: -10px;
|
||||
display: block;
|
||||
font-weight: 400;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 800px) {
|
||||
.onboarding-main {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-image: url('/assets/mobile-onboarding-background.png');
|
||||
background-size: cover;
|
||||
/* Center the image */
|
||||
background-position: center;
|
||||
/* Do not repeat the image */
|
||||
background-repeat: no-repeat;
|
||||
border: none;
|
||||
color: $black;
|
||||
}
|
||||
|
||||
.onboarding-content {
|
||||
flex: 0 0 auto;
|
||||
|
||||
h1,
|
||||
h2 {
|
||||
margin-top: initial;
|
||||
}
|
||||
}
|
||||
|
||||
span {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 650px) {
|
||||
.onboarding-main {
|
||||
font-size: 18px;
|
||||
}
|
||||
justify-content: space-between;
|
||||
padding: $su-4;
|
||||
|
||||
button {
|
||||
width: 100px;
|
||||
font-size: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 450px) {
|
||||
.onboarding-main {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
button {
|
||||
width: 100px;
|
||||
font-size: 18px;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 330px) {
|
||||
button {
|
||||
width: 80px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.sticker-logo {
|
||||
height: 40px;
|
||||
width: 40px;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 20px;
|
||||
@extend .crayons-btn;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// modal header
|
||||
.onboarding-content-header {
|
||||
margin-bottom: $su-4;
|
||||
|
||||
@media screen and (min-width: $breakpoint-s) {
|
||||
margin-bottom: $su-6;
|
||||
}
|
||||
|
||||
.title,
|
||||
.subtitle {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-weight: $fw-heavy;
|
||||
margin-bottom: $su-1;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.subtitle {
|
||||
color: var(--container-color-secondary);
|
||||
font-size: $fs-xl;
|
||||
font-weight: $fw-medium;
|
||||
letter-spacing: normal;
|
||||
line-height: $lh-base;
|
||||
}
|
||||
}
|
||||
|
||||
// modal selection status
|
||||
.onboarding-selection-status {
|
||||
align-self: flex-end;
|
||||
flex-shrink: 0;
|
||||
width: 100%;
|
||||
border-top: 2px solid var(--box-darker);
|
||||
|
||||
.selection-status-content {
|
||||
display: block;
|
||||
padding: $su-4;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
// override crayons notice
|
||||
.onboarding-body {
|
||||
.crayons-notice {
|
||||
display: block;
|
||||
margin-bottom: $su-2;
|
||||
}
|
||||
}
|
||||
// modal overflow scrolling
|
||||
.onboarding-modal-scroll-container {
|
||||
height: auto;
|
||||
|
||||
@media screen and (min-width: $breakpoint-s) {
|
||||
max-height: 500px;
|
||||
overflow-y: scroll;
|
||||
position: relative;
|
||||
}
|
||||
}
|
||||
|
||||
// tag styles
|
||||
.onboarding-tags {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
grid-gap: $su-4;
|
||||
width: 100%;
|
||||
|
||||
@media screen and (min-width: 800px) {
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
}
|
||||
|
||||
&__button {
|
||||
@extend .crayons-btn;
|
||||
border: 0;
|
||||
display: block;
|
||||
position: absolute;
|
||||
left: $su-4;
|
||||
right: $su-4;
|
||||
bottom: $su-4;
|
||||
width: calc(100% - 32px);
|
||||
transform: translateY(0px);
|
||||
font-family: $ff-default;
|
||||
$button: &;
|
||||
|
||||
@media screen and (min-width: 800px) {
|
||||
transform: translateY(60px);
|
||||
}
|
||||
|
||||
&-default {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
&-alt {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
&__item {
|
||||
border-radius: $br-default;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
height: 150px;
|
||||
$item: &;
|
||||
|
||||
&__inner {
|
||||
background: var(--base-10);
|
||||
bottom: 0;
|
||||
font-family: $ff-accent;
|
||||
hyphens: auto;
|
||||
left: 0;
|
||||
padding: $su-4;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
transition: all ease-in-out 0.1s;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
#{$item}__inner {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.onboarding-tags__button {
|
||||
transform: translateY(0);
|
||||
|
||||
&:hover {
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&--selected {
|
||||
#{$item}__inner {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
input[type='checkbox']:checked {
|
||||
background: var(--link-brand-color);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Onboarding Intro
|
||||
.onboarding-main.introduction {
|
||||
width: 578px;
|
||||
|
||||
.onboarding-content {
|
||||
background: var(--base-100);
|
||||
color: white;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: start;
|
||||
padding: $su-8;
|
||||
|
||||
@media screen and (min-width: $breakpoint-s) {
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
|
||||
figure {
|
||||
margin: 0 0 $su-2 0;
|
||||
|
||||
.sticker-logo {
|
||||
height: $su-8;
|
||||
width: $su-8;
|
||||
transform: rotate(-30deg);
|
||||
padding: $su-3;
|
||||
vertical-align: middle;
|
||||
}
|
||||
}
|
||||
|
||||
.introduction-title,
|
||||
.introduction-subtitle {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.introduction-title {
|
||||
font-size: $fs-5xl;
|
||||
font-weight: $fw-heavy;
|
||||
line-height: $lh-tight;
|
||||
}
|
||||
|
||||
.introduction-subtitle {
|
||||
font-size: $fs-2xl;
|
||||
font-weight: $fw-normal;
|
||||
line-height: $lh-base;
|
||||
}
|
||||
|
||||
.navigation-content {
|
||||
padding: $su-7;
|
||||
justify-content: center;
|
||||
|
||||
button {
|
||||
@extend .crayons-btn;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// follow users slide
|
||||
$onboarding-user-unselected-hover: rgba(71, 85, 235, 0.05);
|
||||
$onboarding-user-selected: rgba(71, 85, 235, 0.1);
|
||||
$onboarding-user-selected-hover: rgba(71, 85, 235, 0.2);
|
||||
|
||||
.onboarding-body {
|
||||
.content-row {
|
||||
align-items: center;
|
||||
border: none;
|
||||
box-sizing: border-box;
|
||||
color: var(--body-color);
|
||||
display: flex;
|
||||
padding: $su-2 $su-4;
|
||||
text-align: left;
|
||||
width: 100%;
|
||||
|
||||
&.unselected {
|
||||
&:hover {
|
||||
background-color: $onboarding-user-unselected-hover;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
button {
|
||||
@extend .crayons-btn;
|
||||
@extend .crayons-btn--outlined;
|
||||
}
|
||||
}
|
||||
|
||||
&.selected {
|
||||
background-color: $onboarding-user-selected;
|
||||
|
||||
&:hover {
|
||||
background-color: $onboarding-user-selected-hover;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
button {
|
||||
@extend .crayons-btn;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.user-avatar-container {
|
||||
align-self: baseline;
|
||||
margin: 0 $su-4 0 0;
|
||||
|
||||
@media screen and (min-width: $breakpoint-s) {
|
||||
align-self: center;
|
||||
}
|
||||
}
|
||||
|
||||
.user-avatar {
|
||||
border-radius: 100%;
|
||||
height: $su-8;
|
||||
width: $su-8;
|
||||
object-fit: cover;
|
||||
border: 1px solid var(--base-10);
|
||||
}
|
||||
|
||||
.user-name,
|
||||
.user-summary {
|
||||
margin: 0;
|
||||
line-height: $lh-tight;
|
||||
}
|
||||
|
||||
.user-name {
|
||||
font-size: $fs-base;
|
||||
}
|
||||
|
||||
.user-summary {
|
||||
font-size: $fs-s;
|
||||
}
|
||||
|
||||
.user-following-status {
|
||||
margin-left: $su-7;
|
||||
}
|
||||
}
|
||||
|
||||
// closing slide
|
||||
.onboarding-what-next {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: auto;
|
||||
|
||||
@media screen and (min-width: $breakpoint-s) {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
p {
|
||||
align-items: center;
|
||||
display: inline-flex;
|
||||
}
|
||||
|
||||
a {
|
||||
background: #d9e7ff;
|
||||
margin: 4px auto;
|
||||
border-radius: 3px;
|
||||
display: block;
|
||||
font-weight: 800;
|
||||
width: 100%;
|
||||
padding: 0.25em;
|
||||
position: relative;
|
||||
text-align: center;
|
||||
|
||||
.whatnext-emoji {
|
||||
text-align: center;
|
||||
font-size: 32px;
|
||||
margin-right: 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.onboarding-previous-location {
|
||||
text-align: center;
|
||||
margin-top: 10px;
|
||||
font-weight: bold;
|
||||
display: none;
|
||||
|
||||
@media screen and (min-width: 600px) {
|
||||
display: block;
|
||||
}
|
||||
|
||||
code {
|
||||
font-size: 0.6em;
|
||||
margin-top: -10px;
|
||||
display: block;
|
||||
font-weight: 400;
|
||||
}
|
||||
}
|
||||
|
||||
// Follow user
|
||||
.onboarding-body {
|
||||
.content-row {
|
||||
align-items: center;
|
||||
color: #202428;
|
||||
display: flex;
|
||||
padding: 8px 16px;
|
||||
text-align: left;
|
||||
width: 100%;
|
||||
|
||||
&:hover {
|
||||
background-color: #eef0f1 !important;
|
||||
}
|
||||
}
|
||||
|
||||
.user-avatar-container {
|
||||
margin: 0 16px 0 0;
|
||||
}
|
||||
|
||||
.user-avatar {
|
||||
border-radius: 100%;
|
||||
height: 48px;
|
||||
width: 48px;
|
||||
object-fit: cover;
|
||||
border: 1px solid #eef0f1;
|
||||
}
|
||||
|
||||
.user-name,
|
||||
.user-summary {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.user-following-status {
|
||||
margin-left: 32px;
|
||||
}
|
||||
}
|
||||
|
||||
// Forms
|
||||
.onboarding-main {
|
||||
fieldset {
|
||||
padding: 0;
|
||||
border: none;
|
||||
margin-bottom: $su-6;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
ul {
|
||||
list-style-type: none;
|
||||
margin: 0;
|
||||
padding-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
legend {
|
||||
color: var(--body-color);
|
||||
font-weight: $fw-medium;
|
||||
}
|
||||
|
||||
input[type='text'],
|
||||
textarea {
|
||||
@extend .crayons-textfield;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
textarea {
|
||||
min-height: 120px;
|
||||
}
|
||||
|
||||
label {
|
||||
@extend .crayons-field;
|
||||
@extend .crayons-field__label;
|
||||
margin-bottom: $su-4;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Checkboxes
|
||||
.checkbox-item {
|
||||
label {
|
||||
@extend .crayons-field__label;
|
||||
align-items: baseline;
|
||||
border-radius: $br-default;
|
||||
display: inline-block;
|
||||
flex-direction: row;
|
||||
padding: 0 $su-1;
|
||||
width: 100%;
|
||||
|
||||
@media screen and (min-width: $breakpoint-s) {
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background: var(--body-bg);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
a {
|
||||
display: contents;
|
||||
}
|
||||
|
||||
input[type='checkbox'] {
|
||||
@extend .crayons-checkbox;
|
||||
margin-right: $su-2 !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ import FollowUsers from '../components/FollowUsers';
|
|||
global.fetch = fetch;
|
||||
|
||||
function flushPromises() {
|
||||
return new Promise(resolve => setImmediate(resolve));
|
||||
return new Promise((resolve) => setImmediate(resolve));
|
||||
}
|
||||
|
||||
function initializeSlides(currentSlide, dataUser = null, mockData = null) {
|
||||
|
|
@ -284,18 +284,19 @@ describe('<Onboarding />', () => {
|
|||
});
|
||||
|
||||
test('should render three tags', async () => {
|
||||
expect(onboardingSlides.find('.tag').length).toBe(3);
|
||||
expect(onboardingSlides.find('.onboarding-tags__item').length).toBe(3);
|
||||
});
|
||||
|
||||
test('should allow a user to add a tag', async () => {
|
||||
fetch.once({});
|
||||
const followTags = onboardingSlides.find(<FollowTags />);
|
||||
const firstButton = onboardingSlides
|
||||
.find('.onboarding-tags__button')
|
||||
.first();
|
||||
|
||||
onboardingSlides
|
||||
.find('.tag')
|
||||
.first()
|
||||
.simulate('click');
|
||||
firstButton.simulate('click');
|
||||
expect(followTags.state('selectedTags').length).toBe(1);
|
||||
|
||||
onboardingSlides.find('.next-button').simulate('click');
|
||||
fetch.once(fakeUsersResponse);
|
||||
await flushPromises();
|
||||
|
|
@ -328,10 +329,7 @@ describe('<Onboarding />', () => {
|
|||
fetch.once({});
|
||||
const followUsers = onboardingSlides.find(<FollowUsers />);
|
||||
|
||||
onboardingSlides
|
||||
.find('.user')
|
||||
.first()
|
||||
.simulate('click');
|
||||
onboardingSlides.find('.user').first().simulate('click');
|
||||
expect(followUsers.state('selectedUsers').length).toBe(2);
|
||||
onboardingSlides.find('.next-button').simulate('click');
|
||||
await flushPromises();
|
||||
|
|
|
|||
|
|
@ -5,13 +5,37 @@ preact-render-spy (1 nodes)
|
|||
-------
|
||||
<main class="onboarding-body">
|
||||
<div class="onboarding-main">
|
||||
<nav class="onboarding-navigation">
|
||||
<div class="navigation-content">
|
||||
<button
|
||||
onClick={[Function bound prevSlide]}
|
||||
class="back-button"
|
||||
type="button"
|
||||
>
|
||||
Back
|
||||
</button>
|
||||
<button
|
||||
onClick={[Function bound onSubmit]}
|
||||
class="next-button"
|
||||
type="button"
|
||||
>
|
||||
Continue
|
||||
</button>
|
||||
</div>
|
||||
</nav>
|
||||
<div class="onboarding-content about">
|
||||
<h2>About You!</h2>
|
||||
<header class="onboarding-content-header">
|
||||
<h1 class="title">Introduce yourself</h1>
|
||||
<h2 class="subtitle">
|
||||
Tell the community about yourself. Write a quick bio about what you do, what you're interested in, or anything else.
|
||||
</h2>
|
||||
</header>
|
||||
<form>
|
||||
<label htmlFor="summary">
|
||||
Tell the community about yourself! Write a quick bio about what you do, what you're interested in, or anything else!
|
||||
Bio
|
||||
<textarea
|
||||
name="summary"
|
||||
placeholder="Tell us about yourself"
|
||||
onChange={[Function bound handleChange]}
|
||||
maxLength="120"
|
||||
>
|
||||
|
|
@ -19,22 +43,6 @@ preact-render-spy (1 nodes)
|
|||
</label>
|
||||
</form>
|
||||
</div>
|
||||
<nav class="onboarding-navigation">
|
||||
<button
|
||||
onClick={[Function bound prevSlide]}
|
||||
class="back-button"
|
||||
type="button"
|
||||
>
|
||||
BACK
|
||||
</button>
|
||||
<button
|
||||
onClick={[Function bound onSubmit]}
|
||||
class="next-button"
|
||||
type="button"
|
||||
>
|
||||
Continue
|
||||
</button>
|
||||
</nav>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
|
|
@ -46,62 +54,68 @@ preact-render-spy (1 nodes)
|
|||
<main class="onboarding-body">
|
||||
<div class="onboarding-main">
|
||||
<div class="onboarding-content">
|
||||
<h1>
|
||||
You‘re part of the community!
|
||||
<span
|
||||
role="img"
|
||||
aria-label="tada"
|
||||
>
|
||||
🎉
|
||||
</span>
|
||||
</h1>
|
||||
<h2 style="text-align: center;">What next?</h2>
|
||||
<header class="onboarding-content-header">
|
||||
<h1 class="title">
|
||||
You‘re a part of the community!
|
||||
<span
|
||||
role="img"
|
||||
aria-label="tada"
|
||||
>
|
||||
🎉
|
||||
</span>
|
||||
</h1>
|
||||
<h2 class="subtitle">What next?</h2>
|
||||
</header>
|
||||
<div class="onboarding-what-next">
|
||||
<a
|
||||
href="/welcome"
|
||||
data-no-instant={true}
|
||||
>
|
||||
Join the Welcome Thread
|
||||
<p class="whatnext-emoji">
|
||||
<p>
|
||||
<span
|
||||
class="whatnext-emoji"
|
||||
role="img"
|
||||
aria-label="tada"
|
||||
>
|
||||
😊
|
||||
</span>
|
||||
Join the Welcome Thread
|
||||
</p>
|
||||
</a>
|
||||
<a href="/new">
|
||||
Write your first DEV post
|
||||
<p class="whatnext-emoji">
|
||||
<p>
|
||||
<span
|
||||
class="whatnext-emoji"
|
||||
role="img"
|
||||
aria-label="tada"
|
||||
>
|
||||
✍️
|
||||
</span>
|
||||
Write your first DEV post
|
||||
</p>
|
||||
</a>
|
||||
<a href="/top/infinity">
|
||||
Read all-time top posts
|
||||
<p class="whatnext-emoji">
|
||||
<p>
|
||||
<span
|
||||
class="whatnext-emoji"
|
||||
role="img"
|
||||
aria-label="tada"
|
||||
>
|
||||
🤓
|
||||
</span>
|
||||
Read all-time top posts
|
||||
</p>
|
||||
</a>
|
||||
<a href="/settings">
|
||||
Customize your profile
|
||||
<p class="whatnext-emoji">
|
||||
<p>
|
||||
<span
|
||||
class="whatnext-emoji"
|
||||
role="img"
|
||||
aria-label="tada"
|
||||
>
|
||||
💅
|
||||
</span>
|
||||
Customize your profile
|
||||
</p>
|
||||
</a>
|
||||
</div>
|
||||
|
|
@ -116,82 +130,104 @@ preact-render-spy (1 nodes)
|
|||
-------
|
||||
<main class="onboarding-body">
|
||||
<div class="onboarding-main">
|
||||
<nav class="onboarding-navigation">
|
||||
<div class="navigation-content">
|
||||
<button
|
||||
onClick={[Function bound prevSlide]}
|
||||
class="back-button"
|
||||
type="button"
|
||||
>
|
||||
Back
|
||||
</button>
|
||||
<button
|
||||
onClick={[Function bound onSubmit]}
|
||||
class="next-button"
|
||||
type="button"
|
||||
>
|
||||
Continue
|
||||
</button>
|
||||
</div>
|
||||
</nav>
|
||||
<div class="onboarding-content checkbox-slide">
|
||||
<h2>Some things to check off!</h2>
|
||||
<header class="onboarding-content-header">
|
||||
<h1 class="title">Getting started</h1>
|
||||
<h2 class="subtitle">Let's review a few things first</h2>
|
||||
</header>
|
||||
<form>
|
||||
<label htmlFor="checked_code_of_conduct">
|
||||
<input
|
||||
type="checkbox"
|
||||
id="checked_code_of_conduct"
|
||||
name="checked_code_of_conduct"
|
||||
checked={false}
|
||||
onChange={[Function bound handleChange]}
|
||||
/>
|
||||
You agree to uphold our
|
||||
<a
|
||||
href="/code-of-conduct"
|
||||
data-no-instant={true}
|
||||
onClick={[Function onClick]}
|
||||
>
|
||||
Code of Conduct
|
||||
</a>
|
||||
</label>
|
||||
<label htmlFor="checked_terms_and_conditions">
|
||||
<input
|
||||
type="checkbox"
|
||||
id="checked_terms_and_conditions"
|
||||
name="checked_terms_and_conditions"
|
||||
checked={false}
|
||||
onChange={[Function bound handleChange]}
|
||||
/>
|
||||
You agree to our
|
||||
<a
|
||||
href="/terms"
|
||||
data-no-instant={true}
|
||||
onClick={[Function onClick]}
|
||||
>
|
||||
Terms and Conditions
|
||||
</a>
|
||||
</label>
|
||||
<h3>Email Preferences</h3>
|
||||
<label htmlFor="email_newsletter">
|
||||
<input
|
||||
type="checkbox"
|
||||
id="email_newsletter"
|
||||
name="email_newsletter"
|
||||
checked={true}
|
||||
onChange={[Function bound handleChange]}
|
||||
/>
|
||||
Do you want to receive our weekly newsletter emails?
|
||||
</label>
|
||||
<label htmlFor="email_digest_periodic">
|
||||
<input
|
||||
type="checkbox"
|
||||
id="email_digest_periodic"
|
||||
name="email_digest_periodic"
|
||||
checked={true}
|
||||
onChange={[Function bound handleChange]}
|
||||
/>
|
||||
Do you want to receive a periodic digest with some of the top posts from your tags?
|
||||
</label>
|
||||
<fieldset>
|
||||
<legend>Some things to check off</legend>
|
||||
<ul>
|
||||
<li class="checkbox-item">
|
||||
<label htmlFor="checked_code_of_conduct">
|
||||
<input
|
||||
type="checkbox"
|
||||
id="checked_code_of_conduct"
|
||||
name="checked_code_of_conduct"
|
||||
checked={false}
|
||||
onChange={[Function bound handleChange]}
|
||||
/>
|
||||
I agree to uphold the
|
||||
<a
|
||||
href="/code-of-conduct"
|
||||
data-no-instant={true}
|
||||
onClick={[Function onClick]}
|
||||
>
|
||||
Code of Conduct
|
||||
</a>
|
||||
</label>
|
||||
</li>
|
||||
<li class="checkbox-item">
|
||||
<label htmlFor="checked_terms_and_conditions">
|
||||
<input
|
||||
type="checkbox"
|
||||
id="checked_terms_and_conditions"
|
||||
name="checked_terms_and_conditions"
|
||||
checked={false}
|
||||
onChange={[Function bound handleChange]}
|
||||
/>
|
||||
I agree to our
|
||||
<a
|
||||
href="/terms"
|
||||
data-no-instant={true}
|
||||
onClick={[Function onClick]}
|
||||
>
|
||||
Terms and Conditions
|
||||
</a>
|
||||
</label>
|
||||
</li>
|
||||
</ul>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<legend>Email preferences</legend>
|
||||
<ul>
|
||||
<li class="checkbox-item">
|
||||
<label htmlFor="email_newsletter">
|
||||
<input
|
||||
type="checkbox"
|
||||
id="email_newsletter"
|
||||
name="email_newsletter"
|
||||
checked={true}
|
||||
onChange={[Function bound handleChange]}
|
||||
/>
|
||||
I want to receive weekly newsletter emails.
|
||||
</label>
|
||||
</li>
|
||||
<li class="checkbox-item">
|
||||
<label htmlFor="email_digest_periodic">
|
||||
<input
|
||||
type="checkbox"
|
||||
id="email_digest_periodic"
|
||||
name="email_digest_periodic"
|
||||
checked={true}
|
||||
onChange={[Function bound handleChange]}
|
||||
/>
|
||||
I want to receive a periodic digest with some of the top posts from your tags.
|
||||
</label>
|
||||
</li>
|
||||
</ul>
|
||||
</fieldset>
|
||||
</form>
|
||||
</div>
|
||||
<nav class="onboarding-navigation">
|
||||
<button
|
||||
onClick={[Function bound prevSlide]}
|
||||
class="back-button"
|
||||
type="button"
|
||||
>
|
||||
BACK
|
||||
</button>
|
||||
<button
|
||||
onClick={[Function bound onSubmit]}
|
||||
class="next-button"
|
||||
type="button"
|
||||
>
|
||||
Continue
|
||||
</button>
|
||||
</nav>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
|
|
@ -202,54 +238,82 @@ preact-render-spy (1 nodes)
|
|||
-------
|
||||
<main class="onboarding-body">
|
||||
<div class="onboarding-main">
|
||||
<div class="onboarding-content">
|
||||
<h2>Follow tags to customize your feed</h2>
|
||||
<div class="scroll">
|
||||
<nav class="onboarding-navigation">
|
||||
<div class="navigation-content">
|
||||
<button
|
||||
onClick={[Function bound prevSlide]}
|
||||
class="back-button"
|
||||
type="button"
|
||||
onClick={[Function onClick]}
|
||||
style="background-color: #000000; color: #ffffff;"
|
||||
class="tag"
|
||||
>
|
||||
#discuss
|
||||
<div class="onboarding-tag-follow-indicator"></div>
|
||||
Back
|
||||
</button>
|
||||
<button
|
||||
onClick={[Function bound handleComplete]}
|
||||
class="next-button"
|
||||
type="button"
|
||||
onClick={[Function onClick]}
|
||||
style="background-color: #f7df1e; color: #000000;"
|
||||
class="tag"
|
||||
>
|
||||
#javascript
|
||||
<div class="onboarding-tag-follow-indicator"></div>
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
onClick={[Function onClick]}
|
||||
style="background-color: #2a2566; color: #ffffff;"
|
||||
class="tag"
|
||||
>
|
||||
#career
|
||||
<div class="onboarding-tag-follow-indicator"></div>
|
||||
Continue
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<nav class="onboarding-navigation">
|
||||
<button
|
||||
onClick={[Function bound prevSlide]}
|
||||
class="back-button"
|
||||
type="button"
|
||||
>
|
||||
BACK
|
||||
</button>
|
||||
<button
|
||||
onClick={[Function bound handleComplete]}
|
||||
class="next-button"
|
||||
type="button"
|
||||
>
|
||||
Continue
|
||||
</button>
|
||||
</nav>
|
||||
<div class="onboarding-content">
|
||||
<header class="onboarding-content-header">
|
||||
<h1 class="title">What are you interested in?</h1>
|
||||
<h2 class="subtitle">Follow tags to customize your feed</h2>
|
||||
</header>
|
||||
<div class="onboarding-modal-scroll-container">
|
||||
<div class="onboarding-tags">
|
||||
<div
|
||||
class="onboarding-tags__item false"
|
||||
style="box-shadow: inset 0 0 0 2px #000000; color: ;"
|
||||
>
|
||||
<div class="onboarding-tags__item__inner">
|
||||
#discuss
|
||||
<button
|
||||
type="button"
|
||||
onClick={[Function onClick]}
|
||||
class="onboarding-tags__button false"
|
||||
style="background-color: #000000; color: #ffffff;"
|
||||
>
|
||||
+ Follow
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="onboarding-tags__item false"
|
||||
style="box-shadow: inset 0 0 0 2px #f7df1e; color: ;"
|
||||
>
|
||||
<div class="onboarding-tags__item__inner">
|
||||
#javascript
|
||||
<button
|
||||
type="button"
|
||||
onClick={[Function onClick]}
|
||||
class="onboarding-tags__button false"
|
||||
style="background-color: #f7df1e; color: #000000;"
|
||||
>
|
||||
+ Follow
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="onboarding-tags__item false"
|
||||
style="box-shadow: inset 0 0 0 2px #2a2566; color: ;"
|
||||
>
|
||||
<div class="onboarding-tags__item__inner">
|
||||
#career
|
||||
<button
|
||||
type="button"
|
||||
onClick={[Function onClick]}
|
||||
class="onboarding-tags__button false"
|
||||
style="background-color: #2a2566; color: #ffffff;"
|
||||
>
|
||||
+ Follow
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
|
|
@ -260,79 +324,114 @@ preact-render-spy (1 nodes)
|
|||
-------
|
||||
<main class="onboarding-body">
|
||||
<div class="onboarding-main">
|
||||
<nav class="onboarding-navigation">
|
||||
<div class="navigation-content">
|
||||
<button
|
||||
onClick={[Function bound prevSlide]}
|
||||
class="back-button"
|
||||
type="button"
|
||||
>
|
||||
Back
|
||||
</button>
|
||||
<button
|
||||
onClick={[Function bound handleComplete]}
|
||||
class="next-button"
|
||||
type="button"
|
||||
>
|
||||
Continue
|
||||
</button>
|
||||
</div>
|
||||
</nav>
|
||||
<div class="onboarding-content">
|
||||
<h2>
|
||||
Ok, here are some people we picked for you
|
||||
</h2>
|
||||
<div class="scroll">
|
||||
<div class="select-all-button-wrapper">
|
||||
<header class="onboarding-content-header">
|
||||
<h1 class="title">Suggested people to follow</h1>
|
||||
<h2 class="subtitle">Let's review a few things first</h2>
|
||||
</header>
|
||||
<div class="onboarding-modal-scroll-container">
|
||||
<button
|
||||
type="button"
|
||||
onClick={[Function onClick]}
|
||||
onKeyDown={[Function onKeyDown]}
|
||||
class="user content-row selected"
|
||||
>
|
||||
<figure class="user-avatar-container">
|
||||
<img
|
||||
class="user-avatar"
|
||||
src="ben.jpg"
|
||||
alt="profile"
|
||||
/>
|
||||
</figure>
|
||||
<div class="user-info">
|
||||
<h4 class="user-name">Ben Halpern</h4>
|
||||
<p class="user-summary"></p>
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
onClick={[Function onClick]}
|
||||
class="user-following-status"
|
||||
>
|
||||
Select All ✅
|
||||
Following
|
||||
</button>
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
style="background-color: #c7ffe8;"
|
||||
onClick={[Function onClick]}
|
||||
class="user"
|
||||
>
|
||||
<div class="onboarding-user-follow-status">selected</div>
|
||||
<img
|
||||
src="ben.jpg"
|
||||
alt=""
|
||||
/>
|
||||
<span>Ben Halpern</span>
|
||||
<p></p>
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
style="background-color: #c7ffe8;"
|
||||
onClick={[Function onClick]}
|
||||
class="user"
|
||||
onKeyDown={[Function onKeyDown]}
|
||||
class="user content-row selected"
|
||||
>
|
||||
<div class="onboarding-user-follow-status">selected</div>
|
||||
<img
|
||||
src="clown.jpg"
|
||||
alt=""
|
||||
/>
|
||||
<span>Krusty the Clown</span>
|
||||
<p></p>
|
||||
<figure class="user-avatar-container">
|
||||
<img
|
||||
class="user-avatar"
|
||||
src="clown.jpg"
|
||||
alt="profile"
|
||||
/>
|
||||
</figure>
|
||||
<div class="user-info">
|
||||
<h4 class="user-name">Krusty the Clown</h4>
|
||||
<p class="user-summary"></p>
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
class="user-following-status"
|
||||
>
|
||||
Following
|
||||
</button>
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
style="background-color: #c7ffe8;"
|
||||
onClick={[Function onClick]}
|
||||
class="user"
|
||||
onKeyDown={[Function onKeyDown]}
|
||||
class="user content-row selected"
|
||||
>
|
||||
<div class="onboarding-user-follow-status">selected</div>
|
||||
<img
|
||||
src="dev.jpg"
|
||||
alt=""
|
||||
/>
|
||||
<span>dev.to staff</span>
|
||||
<p></p>
|
||||
<figure class="user-avatar-container">
|
||||
<img
|
||||
class="user-avatar"
|
||||
src="dev.jpg"
|
||||
alt="profile"
|
||||
/>
|
||||
</figure>
|
||||
<div class="user-info">
|
||||
<h4 class="user-name">dev.to staff</h4>
|
||||
<p class="user-summary"></p>
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
class="user-following-status"
|
||||
>
|
||||
Following
|
||||
</button>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="onboarding-selection-status">
|
||||
<div class="selection-status-content">
|
||||
<button
|
||||
type="button"
|
||||
onClick={[Function onClick]}
|
||||
>
|
||||
Select All ✅
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<nav class="onboarding-navigation">
|
||||
<button
|
||||
onClick={[Function bound prevSlide]}
|
||||
class="back-button"
|
||||
type="button"
|
||||
>
|
||||
BACK
|
||||
</button>
|
||||
<button
|
||||
onClick={[Function bound handleComplete]}
|
||||
class="next-button"
|
||||
type="button"
|
||||
>
|
||||
Continue
|
||||
</button>
|
||||
</nav>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
|
|
@ -342,51 +441,30 @@ exports[`<Onboarding /> IntroSlide renders properly 1`] = `
|
|||
preact-render-spy (1 nodes)
|
||||
-------
|
||||
<main class="onboarding-body">
|
||||
<div class="onboarding-main">
|
||||
<div class="onboarding-main introduction">
|
||||
<div class="onboarding-content">
|
||||
<h1>
|
||||
<span>Welcome to the </span>
|
||||
<figure>
|
||||
<img
|
||||
src="/assets/purple-dev-logo.png"
|
||||
class="sticker-logo"
|
||||
alt="DEV"
|
||||
/>
|
||||
<span>community!</span>
|
||||
</h1>
|
||||
<div>
|
||||
<p>
|
||||
DEV is where programmers share ideas and help each other grow.
|
||||
<span
|
||||
role="img"
|
||||
aria-label="Nerd Face"
|
||||
>
|
||||
🤓
|
||||
</span>
|
||||
</p>
|
||||
<p>
|
||||
Ask questions, leave helpful comments, encourage others, and have fun!
|
||||
<span
|
||||
role="img"
|
||||
aria-label="Raising Hands"
|
||||
>
|
||||
🙌
|
||||
</span>
|
||||
</p>
|
||||
<p>
|
||||
A few
|
||||
<strong>quick questions</strong>
|
||||
for you before you get started...
|
||||
</p>
|
||||
</div>
|
||||
</figure>
|
||||
<h1 class="introduction-title">Welcome to DEV!</h1>
|
||||
<h2 class="introduction-subtitle">
|
||||
DEV is where programmers share ideas and help each other grow.
|
||||
</h2>
|
||||
</div>
|
||||
<nav class="onboarding-navigation">
|
||||
<button
|
||||
onClick={[Function bound onSubmit]}
|
||||
class="next-button"
|
||||
type="button"
|
||||
>
|
||||
Continue
|
||||
</button>
|
||||
<div class="navigation-content">
|
||||
<button
|
||||
onClick={[Function bound onSubmit]}
|
||||
class="next-button"
|
||||
type="button"
|
||||
>
|
||||
Continue
|
||||
</button>
|
||||
</div>
|
||||
</nav>
|
||||
</div>
|
||||
</main>
|
||||
|
|
@ -398,8 +476,28 @@ preact-render-spy (1 nodes)
|
|||
-------
|
||||
<main class="onboarding-body">
|
||||
<div class="onboarding-main">
|
||||
<div class="onboarding-content about">
|
||||
<h2>About You!</h2>
|
||||
<nav class="onboarding-navigation">
|
||||
<div class="navigation-content">
|
||||
<button
|
||||
onClick={[Function bound prevSlide]}
|
||||
class="back-button"
|
||||
type="button"
|
||||
>
|
||||
Back
|
||||
</button>
|
||||
<button
|
||||
onClick={[Function bound onSubmit]}
|
||||
class="next-button"
|
||||
type="button"
|
||||
>
|
||||
Continue
|
||||
</button>
|
||||
</div>
|
||||
</nav>
|
||||
<div class="onboarding-content">
|
||||
<header class="onboarding-content-header">
|
||||
<h1 class="title">About You</h1>
|
||||
</header>
|
||||
<form>
|
||||
<label htmlFor="location">
|
||||
Where are you located?
|
||||
|
|
@ -407,6 +505,7 @@ preact-render-spy (1 nodes)
|
|||
type="text"
|
||||
name="location"
|
||||
id="location"
|
||||
placeholder="e.g. New York, NY"
|
||||
onChange={[Function bound handleChange]}
|
||||
maxLength="60"
|
||||
/>
|
||||
|
|
@ -417,6 +516,7 @@ preact-render-spy (1 nodes)
|
|||
type="text"
|
||||
name="employment_title"
|
||||
id="employment_title"
|
||||
placeholder="e.g. Software Engineer"
|
||||
onChange={[Function bound handleChange]}
|
||||
maxLength="60"
|
||||
/>
|
||||
|
|
@ -427,28 +527,13 @@ preact-render-spy (1 nodes)
|
|||
type="text"
|
||||
name="employer_name"
|
||||
id="employer_name"
|
||||
placeholder="e.g. Company name, self-employed, etc."
|
||||
onChange={[Function bound handleChange]}
|
||||
maxLength="60"
|
||||
/>
|
||||
</label>
|
||||
</form>
|
||||
</div>
|
||||
<nav class="onboarding-navigation">
|
||||
<button
|
||||
onClick={[Function bound prevSlide]}
|
||||
class="back-button"
|
||||
type="button"
|
||||
>
|
||||
BACK
|
||||
</button>
|
||||
<button
|
||||
onClick={[Function bound onSubmit]}
|
||||
class="next-button"
|
||||
type="button"
|
||||
>
|
||||
Continue
|
||||
</button>
|
||||
</nav>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
|
|
|
|||
|
|
@ -51,21 +51,27 @@ class BioForm extends Component {
|
|||
const { prev } = this.props;
|
||||
return (
|
||||
<div className="onboarding-main">
|
||||
<Navigation prev={prev} next={this.onSubmit} />
|
||||
<div className="onboarding-content about">
|
||||
<h2>About You!</h2>
|
||||
<header className="onboarding-content-header">
|
||||
<h1 className="title">Introduce yourself</h1>
|
||||
<h2 className="subtitle">
|
||||
Tell the community about yourself. Write a quick bio about what
|
||||
you do, what you're interested in, or anything else.
|
||||
</h2>
|
||||
</header>
|
||||
<form>
|
||||
<label htmlFor="summary">
|
||||
Tell the community about yourself! Write a quick bio about what
|
||||
you do, what you're interested in, or anything else!
|
||||
Bio
|
||||
<textarea
|
||||
name="summary"
|
||||
placeholder="Tell us about yourself"
|
||||
onChange={this.handleChange}
|
||||
maxLength="120"
|
||||
/>
|
||||
</label>
|
||||
</form>
|
||||
</div>
|
||||
<Navigation prev={prev} next={this.onSubmit} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,7 +27,11 @@ class ClosingSlide extends Component {
|
|||
</div>
|
||||
);
|
||||
}
|
||||
if (previousLocation !== 'none' && previousLocation !== null && !previousLocation.startsWith('javascript')) {
|
||||
if (
|
||||
previousLocation !== 'none' &&
|
||||
previousLocation !== null &&
|
||||
!previousLocation.startsWith('javascript')
|
||||
) {
|
||||
return (
|
||||
<a className="onboarding-previous-location" href={previousLocation}>
|
||||
<div>Or go back to the page you were on before you signed up</div>
|
||||
|
|
@ -119,35 +123,35 @@ class ClosingSlide extends Component {
|
|||
return (
|
||||
<div className="onboarding-what-next">
|
||||
<a href="/welcome" data-no-instant>
|
||||
Join the Welcome Thread
|
||||
<p className="whatnext-emoji">
|
||||
<span role="img" aria-label="tada">
|
||||
<p>
|
||||
<span className="whatnext-emoji" role="img" aria-label="tada">
|
||||
😊
|
||||
</span>
|
||||
Join the Welcome Thread
|
||||
</p>
|
||||
</a>
|
||||
<a href="/new">
|
||||
Write your first DEV post
|
||||
<p className="whatnext-emoji">
|
||||
<span role="img" aria-label="tada">
|
||||
<p>
|
||||
<span className="whatnext-emoji" role="img" aria-label="tada">
|
||||
✍️
|
||||
</span>
|
||||
Write your first DEV post
|
||||
</p>
|
||||
</a>
|
||||
<a href="/top/infinity">
|
||||
Read all-time top posts
|
||||
<p className="whatnext-emoji">
|
||||
<span role="img" aria-label="tada">
|
||||
<p>
|
||||
<span className="whatnext-emoji" role="img" aria-label="tada">
|
||||
🤓
|
||||
</span>
|
||||
Read all-time top posts
|
||||
</p>
|
||||
</a>
|
||||
<a href="/settings">
|
||||
Customize your profile
|
||||
<p className="whatnext-emoji">
|
||||
<span role="img" aria-label="tada">
|
||||
<p>
|
||||
<span className="whatnext-emoji" role="img" aria-label="tada">
|
||||
💅
|
||||
</span>
|
||||
Customize your profile
|
||||
</p>
|
||||
</a>
|
||||
</div>
|
||||
|
|
@ -157,14 +161,17 @@ class ClosingSlide extends Component {
|
|||
return (
|
||||
<div className="onboarding-main">
|
||||
<div className="onboarding-content">
|
||||
<h1>
|
||||
You‘re part of the community!
|
||||
<span role="img" aria-label="tada">
|
||||
{' '}
|
||||
🎉
|
||||
</span>
|
||||
</h1>
|
||||
<h2 style={{ textAlign: 'center' }}>What next?</h2>
|
||||
<header className="onboarding-content-header">
|
||||
<h1 className="title">
|
||||
You‘re a part of the community!
|
||||
<span role="img" aria-label="tada">
|
||||
{' '}
|
||||
🎉
|
||||
</span>
|
||||
</h1>
|
||||
<h2 className="subtitle">What next?</h2>
|
||||
</header>
|
||||
|
||||
{nextStepLinks()}
|
||||
{previousLocationListElement()}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -58,14 +58,14 @@ class EmailTermsConditionsForm extends Component {
|
|||
} = this.state;
|
||||
if (!checked_code_of_conduct) {
|
||||
this.setState({
|
||||
message: 'You must agree to our Code of Conduct before continuing!',
|
||||
message: 'You must agree to our Code of Conduct before continuing.',
|
||||
});
|
||||
return false;
|
||||
}
|
||||
if (!checked_terms_and_conditions) {
|
||||
this.setState({
|
||||
message:
|
||||
'You must agree to our Terms and Conditions before continuing!',
|
||||
'You must agree to our Terms and Conditions before continuing.',
|
||||
});
|
||||
return false;
|
||||
}
|
||||
|
|
@ -103,7 +103,7 @@ class EmailTermsConditionsForm extends Component {
|
|||
<div className="onboarding-main">
|
||||
<div className="onboarding-content checkbox-slide">
|
||||
<button type="button" onClick={() => this.backToSlide()}>
|
||||
BACK
|
||||
Back
|
||||
</button>
|
||||
<div
|
||||
/* eslint-disable react/no-danger */
|
||||
|
|
@ -117,72 +117,99 @@ class EmailTermsConditionsForm extends Component {
|
|||
}
|
||||
return (
|
||||
<div className="onboarding-main">
|
||||
<Navigation prev={prev} next={this.onSubmit} />
|
||||
<div className="onboarding-content checkbox-slide">
|
||||
<h2>Some things to check off!</h2>
|
||||
{message && <span className="warning-message">{message}</span>}
|
||||
<form>
|
||||
<label htmlFor="checked_code_of_conduct">
|
||||
<input
|
||||
type="checkbox"
|
||||
id="checked_code_of_conduct"
|
||||
name="checked_code_of_conduct"
|
||||
checked={checked_code_of_conduct}
|
||||
onChange={this.handleChange}
|
||||
/>
|
||||
You agree to uphold our
|
||||
{' '}
|
||||
<a
|
||||
href="/code-of-conduct"
|
||||
data-no-instant
|
||||
onClick={e => this.handleShowText(e, 'coc')}
|
||||
>
|
||||
Code of Conduct
|
||||
</a>
|
||||
</label>
|
||||
<label htmlFor="checked_terms_and_conditions">
|
||||
<input
|
||||
type="checkbox"
|
||||
id="checked_terms_and_conditions"
|
||||
name="checked_terms_and_conditions"
|
||||
checked={checked_terms_and_conditions}
|
||||
onChange={this.handleChange}
|
||||
/>
|
||||
You agree to our
|
||||
{' '}
|
||||
<a
|
||||
href="/terms"
|
||||
data-no-instant
|
||||
onClick={e => this.handleShowText(e, 'terms')}
|
||||
>
|
||||
Terms and Conditions
|
||||
</a>
|
||||
</label>
|
||||
<h3>Email Preferences</h3>
|
||||
<label htmlFor="email_newsletter">
|
||||
<input
|
||||
type="checkbox"
|
||||
id="email_newsletter"
|
||||
name="email_newsletter"
|
||||
checked={email_newsletter}
|
||||
onChange={this.handleChange}
|
||||
/>
|
||||
Do you want to receive our weekly newsletter emails?
|
||||
</label>
|
||||
<header className="onboarding-content-header">
|
||||
<h1 className="title">Getting started</h1>
|
||||
<h2 className="subtitle">Let's review a few things first</h2>
|
||||
</header>
|
||||
|
||||
<label htmlFor="email_digest_periodic">
|
||||
<input
|
||||
type="checkbox"
|
||||
id="email_digest_periodic"
|
||||
name="email_digest_periodic"
|
||||
checked={email_digest_periodic}
|
||||
onChange={this.handleChange}
|
||||
/>
|
||||
Do you want to receive a periodic digest with some of the top
|
||||
posts from your tags?
|
||||
</label>
|
||||
{message && (
|
||||
<span className="crayons-notice crayons-notice--danger">
|
||||
{message}
|
||||
</span>
|
||||
)}
|
||||
|
||||
<form>
|
||||
<fieldset>
|
||||
<legend>Some things to check off</legend>
|
||||
<ul>
|
||||
<li className="checkbox-item">
|
||||
<label htmlFor="checked_code_of_conduct">
|
||||
<input
|
||||
type="checkbox"
|
||||
id="checked_code_of_conduct"
|
||||
name="checked_code_of_conduct"
|
||||
checked={checked_code_of_conduct}
|
||||
onChange={this.handleChange}
|
||||
/>
|
||||
I agree to uphold the
|
||||
{' '}
|
||||
<a
|
||||
href="/code-of-conduct"
|
||||
data-no-instant
|
||||
onClick={e => this.handleShowText(e, 'coc')}
|
||||
>
|
||||
Code of Conduct
|
||||
</a>
|
||||
</label>
|
||||
</li>
|
||||
|
||||
<li className="checkbox-item">
|
||||
<label htmlFor="checked_terms_and_conditions">
|
||||
<input
|
||||
type="checkbox"
|
||||
id="checked_terms_and_conditions"
|
||||
name="checked_terms_and_conditions"
|
||||
checked={checked_terms_and_conditions}
|
||||
onChange={this.handleChange}
|
||||
/>
|
||||
I agree to our
|
||||
{' '}
|
||||
<a
|
||||
href="/terms"
|
||||
data-no-instant
|
||||
onClick={e => this.handleShowText(e, 'terms')}
|
||||
>
|
||||
Terms and Conditions
|
||||
</a>
|
||||
</label>
|
||||
</li>
|
||||
</ul>
|
||||
</fieldset>
|
||||
|
||||
<fieldset>
|
||||
<legend>Email preferences</legend>
|
||||
<ul>
|
||||
<li className="checkbox-item">
|
||||
<label htmlFor="email_newsletter">
|
||||
<input
|
||||
type="checkbox"
|
||||
id="email_newsletter"
|
||||
name="email_newsletter"
|
||||
checked={email_newsletter}
|
||||
onChange={this.handleChange}
|
||||
/>
|
||||
I want to receive weekly newsletter emails.
|
||||
</label>
|
||||
</li>
|
||||
<li className="checkbox-item">
|
||||
<label htmlFor="email_digest_periodic">
|
||||
<input
|
||||
type="checkbox"
|
||||
id="email_digest_periodic"
|
||||
name="email_digest_periodic"
|
||||
checked={email_digest_periodic}
|
||||
onChange={this.handleChange}
|
||||
/>
|
||||
I want to receive a periodic digest with some of the top
|
||||
posts from your tags.
|
||||
</label>
|
||||
</li>
|
||||
</ul>
|
||||
</fieldset>
|
||||
</form>
|
||||
</div>
|
||||
<Navigation prev={prev} next={this.onSubmit} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -85,31 +85,63 @@ class FollowTags extends Component {
|
|||
const { selectedTags, allTags } = this.state;
|
||||
return (
|
||||
<div className="onboarding-main">
|
||||
<Navigation prev={prev} next={this.handleComplete} />
|
||||
<div className="onboarding-content">
|
||||
<h2>Follow tags to customize your feed</h2>
|
||||
<div className="scroll">
|
||||
{allTags.map(tag => (
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => this.handleClick(tag)}
|
||||
style={{
|
||||
backgroundColor: tag.bg_color_hex,
|
||||
color: tag.text_color_hex,
|
||||
}}
|
||||
className={
|
||||
selectedTags.includes(tag) ? 'tag tag-selected' : 'tag'
|
||||
}
|
||||
>
|
||||
#
|
||||
{tag.name}
|
||||
<div className="onboarding-tag-follow-indicator">
|
||||
{selectedTags.includes(tag) ? '✓ following ' : ''}
|
||||
<header className="onboarding-content-header">
|
||||
<h1 className="title">What are you interested in?</h1>
|
||||
<h2 className="subtitle">Follow tags to customize your feed</h2>
|
||||
</header>
|
||||
<div className="onboarding-modal-scroll-container">
|
||||
<div className="onboarding-tags">
|
||||
{allTags.map(tag => (
|
||||
<div
|
||||
className={`onboarding-tags__item ${selectedTags.includes(
|
||||
tag,
|
||||
) && 'onboarding-tags__item--selected'}`}
|
||||
style={{
|
||||
boxShadow: selectedTags.includes(tag)
|
||||
? `inset 0 0 0 100px ${tag.bg_color_hex}`
|
||||
: `inset 0 0 0 2px ${tag.bg_color_hex}`,
|
||||
color: selectedTags.includes(tag) ? tag.text_color_hex : '',
|
||||
}}
|
||||
>
|
||||
<div className="onboarding-tags__item__inner">
|
||||
#
|
||||
{tag.name}
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => this.handleClick(tag)}
|
||||
className={`onboarding-tags__button ${selectedTags.includes(
|
||||
tag,
|
||||
) && 'onboarding-tags__button--selected'}`}
|
||||
style={{
|
||||
backgroundColor: selectedTags.includes(tag)
|
||||
? tag.text_color_hex
|
||||
: tag.bg_color_hex,
|
||||
color: selectedTags.includes(tag)
|
||||
? tag.bg_color_hex
|
||||
: tag.text_color_hex,
|
||||
}}
|
||||
>
|
||||
{selectedTags.includes(tag) ? (
|
||||
<span>
|
||||
<span className="onboarding-tags__button-default">
|
||||
✓ Following
|
||||
</span>
|
||||
<span className="onboarding-tags__button-alt">
|
||||
Unfollow
|
||||
</span>
|
||||
</span>
|
||||
) : (
|
||||
'+ Follow'
|
||||
)}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</button>
|
||||
))}
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<Navigation prev={prev} next={this.handleComplete} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -97,38 +97,52 @@ class FollowUsers extends Component {
|
|||
const { prev } = this.props;
|
||||
return (
|
||||
<div className="onboarding-main">
|
||||
<Navigation prev={prev} next={this.handleComplete} />
|
||||
<div className="onboarding-content">
|
||||
<h2>Ok, here are some people we picked for you</h2>
|
||||
<div className="scroll">
|
||||
<div className="select-all-button-wrapper">
|
||||
<button type="button" onClick={() => this.handleSelectAll()}>
|
||||
Select All
|
||||
{' '}
|
||||
{selectedUsers.length === users.length ? '✅' : ''}
|
||||
</button>
|
||||
</div>
|
||||
<header className="onboarding-content-header">
|
||||
<h1 className="title">Suggested people to follow</h1>
|
||||
<h2 className="subtitle">Let's review a few things first</h2>
|
||||
</header>
|
||||
|
||||
<div className="onboarding-modal-scroll-container">
|
||||
{users.map(user => (
|
||||
<button
|
||||
type="button"
|
||||
style={{
|
||||
backgroundColor: selectedUsers.includes(user)
|
||||
? '#c7ffe8'
|
||||
: 'white',
|
||||
}}
|
||||
onClick={() => this.handleClick(user)}
|
||||
className="user"
|
||||
onKeyDown={() => this.handleKeyDown(user)}
|
||||
className={
|
||||
selectedUsers.includes(user)
|
||||
? 'user content-row selected'
|
||||
: 'user content-row unselected'
|
||||
}
|
||||
>
|
||||
<div className="onboarding-user-follow-status">
|
||||
{selectedUsers.includes(user) ? 'selected' : ''}
|
||||
<figure className="user-avatar-container">
|
||||
<img
|
||||
className="user-avatar"
|
||||
src={user.profile_image_url}
|
||||
alt="profile"
|
||||
/>
|
||||
</figure>
|
||||
<div className="user-info">
|
||||
<h4 className="user-name">{user.name}</h4>
|
||||
<p className="user-summary">{user.summary}</p>
|
||||
</div>
|
||||
<img src={user.profile_image_url} alt="" />
|
||||
<span>{user.name}</span>
|
||||
<p>{user.summary}</p>
|
||||
<button type="button" className="user-following-status">
|
||||
{selectedUsers.includes(user) ? 'Following' : 'Follow'}
|
||||
</button>
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
<Navigation prev={prev} next={this.handleComplete} />
|
||||
<div className="onboarding-selection-status">
|
||||
<div className="selection-status-content">
|
||||
<button type="button" onClick={() => this.handleSelectAll()}>
|
||||
Select All
|
||||
{' '}
|
||||
{selectedUsers.length === users.length ? '✅' : ''}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -78,22 +78,22 @@ class IntroSlide extends Component {
|
|||
}
|
||||
|
||||
render() {
|
||||
const { prev, variant } = this.props;
|
||||
const onboardingBody = this.selectVariant(variant);
|
||||
const { prev } = this.props;
|
||||
|
||||
return (
|
||||
<div className="onboarding-main">
|
||||
<div className="onboarding-main introduction">
|
||||
<div className="onboarding-content">
|
||||
<h1>
|
||||
<span>Welcome to the </span>
|
||||
<figure>
|
||||
<img
|
||||
src="/assets/purple-dev-logo.png"
|
||||
className="sticker-logo"
|
||||
alt="DEV"
|
||||
/>
|
||||
<span>community!</span>
|
||||
</h1>
|
||||
{onboardingBody}
|
||||
</figure>
|
||||
<h1 className="introduction-title">Welcome to DEV!</h1>
|
||||
<h2 className="introduction-subtitle">
|
||||
DEV is where programmers share ideas and help each other grow.
|
||||
</h2>
|
||||
</div>
|
||||
<Navigation prev={prev} next={this.onSubmit} hidePrev />
|
||||
</div>
|
||||
|
|
@ -104,7 +104,6 @@ class IntroSlide extends Component {
|
|||
IntroSlide.propTypes = {
|
||||
prev: PropTypes.func.isRequired,
|
||||
next: PropTypes.string.isRequired,
|
||||
variant: PropTypes.string.isRequired,
|
||||
};
|
||||
|
||||
export default IntroSlide;
|
||||
|
|
|
|||
|
|
@ -3,16 +3,18 @@ import PropTypes from 'prop-types';
|
|||
|
||||
const Navigation = ({ next, prev, hideNext, hidePrev }) => (
|
||||
<nav className="onboarding-navigation">
|
||||
{!hidePrev && (
|
||||
<button onClick={prev} className="back-button" type="button">
|
||||
BACK
|
||||
</button>
|
||||
)}
|
||||
{!hideNext && (
|
||||
<button onClick={next} className="next-button" type="button">
|
||||
Continue
|
||||
</button>
|
||||
)}
|
||||
<div className="navigation-content">
|
||||
{!hidePrev && (
|
||||
<button onClick={prev} className="back-button" type="button">
|
||||
Back
|
||||
</button>
|
||||
)}
|
||||
{!hideNext && (
|
||||
<button onClick={next} className="next-button" type="button">
|
||||
Continue
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
</nav>
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import { getContentOfToken } from '../utilities';
|
|||
const setupFormTextField = ({
|
||||
labelText = '',
|
||||
entityName = '',
|
||||
placeholderText = '',
|
||||
onChangeCallback,
|
||||
}) => {
|
||||
return (
|
||||
|
|
@ -18,6 +19,7 @@ const setupFormTextField = ({
|
|||
type="text"
|
||||
name={entityName}
|
||||
id={entityName}
|
||||
placeholder={placeholderText}
|
||||
onChange={onChangeCallback}
|
||||
maxLength="60"
|
||||
/>
|
||||
|
|
@ -99,27 +101,32 @@ class PersonalInfoForm extends Component {
|
|||
const { prev } = this.props;
|
||||
return (
|
||||
<div className="onboarding-main">
|
||||
<div className="onboarding-content about">
|
||||
<h2>About You!</h2>
|
||||
<Navigation prev={prev} next={this.onSubmit} />
|
||||
<div className="onboarding-content">
|
||||
<header className="onboarding-content-header">
|
||||
<h1 className="title">About You</h1>
|
||||
</header>
|
||||
<form>
|
||||
{setupFormTextField({
|
||||
labelText: 'Where are you located?',
|
||||
entityName: 'location',
|
||||
placeholderText: 'e.g. New York, NY',
|
||||
onChangeCallback: this.handleChange,
|
||||
})}
|
||||
{setupFormTextField({
|
||||
labelText: 'What is your title?',
|
||||
entityName: 'employment_title',
|
||||
placeholderText: 'e.g. Software Engineer',
|
||||
onChangeCallback: this.handleChange,
|
||||
})}
|
||||
{setupFormTextField({
|
||||
labelText: 'Where do you work?',
|
||||
entityName: 'employer_name',
|
||||
placeholderText: 'e.g. Company name, self-employed, etc.',
|
||||
onChangeCallback: this.handleChange,
|
||||
})}
|
||||
</form>
|
||||
</div>
|
||||
<Navigation prev={prev} next={this.onSubmit} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
@ -128,6 +135,7 @@ class PersonalInfoForm extends Component {
|
|||
setupFormTextField.propTypes = {
|
||||
labelText: PropTypes.string.isRequired,
|
||||
entityName: PropTypes.string.isRequired,
|
||||
placeholderText: PropTypes.string.isRequired,
|
||||
onChangeCallback: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue