Adjust onboarding slides (#882)
* Modify onboarding slides * Remove user controller changes * Modify onboarding slide font size * Adjust small onboarding issues * Modify onboarding styling * Remove flash unstyles content
This commit is contained in:
parent
eaf98d738a
commit
991458d1c3
20 changed files with 425 additions and 223 deletions
|
|
@ -8,7 +8,8 @@
|
|||
right:calc(15% - 33px);
|
||||
bottom:calc(15% - 33px);
|
||||
z-index:899900;
|
||||
animation: fadein 0.15s ease ;
|
||||
animation: fadein 0.20s ease ;
|
||||
display: block !important;
|
||||
@keyframes fadein{
|
||||
0% { opacity:0;}
|
||||
100% { opacity:1;}
|
||||
|
|
@ -20,11 +21,11 @@
|
|||
border:0;
|
||||
font-size: 1em;
|
||||
background:transparent;
|
||||
top:4%;
|
||||
left:7%;
|
||||
top:1%;
|
||||
left:1%;
|
||||
cursor:pointer;
|
||||
img{
|
||||
width:calc(0.8vw + 20px);
|
||||
width:calc(0.7vw + 18px);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -36,7 +37,7 @@
|
|||
bottom:0;
|
||||
background-color: #bac5fa;
|
||||
z-index:899901;
|
||||
opacity: 0.9;
|
||||
opacity: 0.97;
|
||||
}
|
||||
|
||||
.yellow{
|
||||
|
|
@ -45,19 +46,22 @@
|
|||
.purple{
|
||||
background: $purple;
|
||||
}
|
||||
.green{
|
||||
background: $green;
|
||||
}
|
||||
|
||||
.modal-header {
|
||||
height: 10%;
|
||||
display:block;
|
||||
font-weight: 500;
|
||||
font-size: 1.1em;
|
||||
max-width: 350px;
|
||||
max-width: 450px;
|
||||
font-family: $helvetica-condensed;
|
||||
font-stretch:condensed;
|
||||
.triangle-isosceles {
|
||||
margin-left: 5px;
|
||||
position:relative;
|
||||
padding:10px 3px;
|
||||
padding:10px 20px;
|
||||
color:white;
|
||||
background:#6091fb;
|
||||
-webkit-border-radius:10px;
|
||||
|
|
@ -85,22 +89,41 @@
|
|||
p {
|
||||
text-align: left;
|
||||
color: black;
|
||||
margin: 0.5em 0px;
|
||||
}
|
||||
.onboarding-initial-welcome {
|
||||
font-weight: bold;
|
||||
font-size: calc( 1.9vw + 2.1vh + 10px);
|
||||
p{
|
||||
margin: 1.2em 0px;
|
||||
}
|
||||
@media screen and (min-width: 800px) {
|
||||
font-size: 48px;
|
||||
}
|
||||
}
|
||||
.sloan-bar {
|
||||
width:15%;
|
||||
float:left;
|
||||
height: 100%;
|
||||
text-align: center;
|
||||
display: none;
|
||||
@media screen and (min-width: 700px) {
|
||||
display: block;
|
||||
}
|
||||
.sloan-img {
|
||||
width:100%;
|
||||
width:96%;
|
||||
}
|
||||
}
|
||||
.body-message {
|
||||
height:100%;
|
||||
width:80%;
|
||||
height:98%;
|
||||
width:95%;
|
||||
padding-left: calc(3% + 2px);
|
||||
max-width: 730px;
|
||||
max-width: 1000px;
|
||||
float:left;
|
||||
font-size: calc(0.8em + 6px);
|
||||
@media screen and (min-width: 700px) {
|
||||
width:80%;
|
||||
}
|
||||
}
|
||||
|
||||
.tags-slide {
|
||||
|
|
@ -112,50 +135,43 @@
|
|||
overflow-y: auto;
|
||||
text-align:left;
|
||||
font-size: calc(0.77em + 6px);
|
||||
height: calc(100vh - 280px);
|
||||
@media screen and (min-width: 900px) {
|
||||
height: 36vh;
|
||||
font-size: 27px;
|
||||
}
|
||||
@media screen and (max-width: 768px) {
|
||||
height: 30vh;
|
||||
}
|
||||
}
|
||||
|
||||
.onboarding-tag-container {
|
||||
background:$black;
|
||||
color:white;
|
||||
background: lighten($light-medium-gray, 1%);
|
||||
color: $black;
|
||||
display:inline-block;
|
||||
font-family: "Lucida Console", Monaco, monospace, sans-serif;
|
||||
position:relative;
|
||||
opacity:0.8;
|
||||
width: 44%;
|
||||
margin-right: 3%;
|
||||
border-radius: 50px;
|
||||
width: 47%;
|
||||
margin-right: 2%;
|
||||
border-radius: 3px;
|
||||
margin-top: calc(0.2vw + 3px);
|
||||
font-size: .75em;
|
||||
border: 6px solid white;
|
||||
margin-bottom: 6px;
|
||||
@media screen and (max-width: 900px) {
|
||||
width: 92%;
|
||||
margin-right: 0%;
|
||||
font-size: .7em;
|
||||
font-size: .66em;
|
||||
}
|
||||
&:hover{
|
||||
opacity:92;
|
||||
background: darken($light-medium-gray, 3%);
|
||||
}
|
||||
&.followed-tag{
|
||||
opacity:1;
|
||||
border: 6px solid $green;
|
||||
box-shadow: 2px 2px 0px $green;
|
||||
a.onboarding-tag-link-follow{
|
||||
background: $green;
|
||||
color: white;
|
||||
background: rgba(255,255,255, 0.1);
|
||||
}
|
||||
}
|
||||
a.onboarding-tag-link{
|
||||
color:white;
|
||||
padding:7px 14px;
|
||||
color: $black;
|
||||
padding:14px 20px;
|
||||
display:inline-block;
|
||||
width:100%;
|
||||
width:calc(100% - 40px);
|
||||
@media screen and (max-width: 900px) {
|
||||
text-align: left;
|
||||
}
|
||||
|
|
@ -163,21 +179,24 @@
|
|||
}
|
||||
a.onboarding-tag-link-follow {
|
||||
position:absolute;
|
||||
right:9px;
|
||||
top: calc(0.7vw - 1px);
|
||||
width:30px;
|
||||
height:30px;
|
||||
right:0px;
|
||||
top: 0px;
|
||||
bottom: 0px;
|
||||
width:60px;
|
||||
text-align:center;
|
||||
color:white;
|
||||
border-radius:100px;
|
||||
color:$black;
|
||||
font-weight:900;
|
||||
line-height:26px;
|
||||
line-height: calc(4vw + 20px);
|
||||
border-top-right-radius: 3px;
|
||||
border-bottom-right-radius: 3px;
|
||||
text-align: center;
|
||||
font-size:1.1em;
|
||||
border-left: 3px solid white;
|
||||
@media screen and (min-width: 900px) {
|
||||
top: 6px;
|
||||
line-height: 55px;
|
||||
}
|
||||
&.following-butt {
|
||||
font-family: "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif;
|
||||
font-family: $helvetica-condensed;
|
||||
top:8px;
|
||||
right:6px;
|
||||
border: 2px solid white;
|
||||
|
|
@ -188,15 +207,16 @@
|
|||
}
|
||||
|
||||
}
|
||||
.onboarding-user-cta{
|
||||
font-size: 1.1em;
|
||||
color: $black;
|
||||
margin: 20px auto 15px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.onboarding-user-container{
|
||||
margin-top: calc(0.5vw + 8px);
|
||||
text-align: left;
|
||||
.onboarding-user-cta{
|
||||
font-size: 0.9em;
|
||||
color: $black;
|
||||
margin: 20px auto 25px;
|
||||
}
|
||||
.onboarding-article-container{
|
||||
color: $black;
|
||||
.onboarding-article-header{
|
||||
|
|
@ -235,10 +255,12 @@
|
|||
.onboarding-user-list{
|
||||
color: $black;
|
||||
font-size: 0.7em;
|
||||
border: 1px solid darken($purple, 20%);
|
||||
box-shadow: 4px 5px 0px darken($purple, 20%);
|
||||
text-align: center;
|
||||
width: 97%;
|
||||
// border: 1px solid darken($purple, 20%);
|
||||
// box-shadow: 4px 5px 0px darken($purple, 20%);
|
||||
.onboarding-user-list-body{
|
||||
height: calc(39vh - 20px);
|
||||
height: calc(65vh - 20px);
|
||||
overflow-y: scroll;
|
||||
.onboarding-user-loading {
|
||||
display: flex;
|
||||
|
|
@ -248,15 +270,56 @@
|
|||
color: $medium-gray;
|
||||
}
|
||||
}
|
||||
|
||||
.onboarding-user-list-header{
|
||||
background: $purple;
|
||||
font-size:1.1em;
|
||||
font-weight: bold;
|
||||
width: calc(100% - 40px);
|
||||
padding: 13px 20px;
|
||||
border-radius: 3px;
|
||||
position: relative;
|
||||
text-align: left;
|
||||
button {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
border: 0;
|
||||
font-size: 1.5em;
|
||||
width: 80px;
|
||||
background: rgba(255,255,255,0.3);
|
||||
color: $bold-blue;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
.onboarding-user-list-row{
|
||||
padding: 10px 0px;
|
||||
padding: 20px 10px 10px;
|
||||
width: 95%;
|
||||
display: inline-block;
|
||||
text-align: left;
|
||||
position: relative;
|
||||
@media screen and (min-width: 1000px) {
|
||||
width: 45%;
|
||||
}
|
||||
&:last-child{
|
||||
margin-bottom: 80px;
|
||||
}
|
||||
img{
|
||||
height: 33px;
|
||||
width: 33px;
|
||||
height: 70px;
|
||||
width: 70px;
|
||||
border-radius: 50%;
|
||||
display: inline-block;
|
||||
vertical-align: -0.5em;
|
||||
margin-right: 10px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.onboarding-user-list-row__summary{
|
||||
color: $medium-gray;
|
||||
font-size: 15px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
.onboarding-article-engagement {
|
||||
font-size: 16px;
|
||||
|
|
@ -273,14 +336,6 @@
|
|||
padding-left: 7px;
|
||||
}
|
||||
}
|
||||
&:nth-child(odd){
|
||||
background: $light-gray;
|
||||
}
|
||||
&.onboarding-user-list-header{
|
||||
background: $purple;
|
||||
font-size:1.1em;
|
||||
font-weight: bold;
|
||||
}
|
||||
.onboarding-user-list-key{
|
||||
width: calc(100% - 80px);
|
||||
display: inline-block;
|
||||
|
|
@ -312,16 +367,14 @@
|
|||
border: 0px;
|
||||
border-radius: 3px;
|
||||
background: transparent;
|
||||
font-size:1.1em;
|
||||
font-size:1.5em;
|
||||
position: absolute;
|
||||
top:25px;
|
||||
right: 8px;
|
||||
padding: 5px 12px;
|
||||
&.checked{
|
||||
background: $green;
|
||||
color: white;
|
||||
&:hover {
|
||||
background: darken($green, 10%);
|
||||
}
|
||||
&:active {
|
||||
background: darken($green, 20%);
|
||||
}
|
||||
background: $purple;
|
||||
color: $black;
|
||||
}
|
||||
&:hover {
|
||||
background: darken($purple, 10%);
|
||||
|
|
@ -367,13 +420,38 @@
|
|||
}
|
||||
|
||||
.modal-footer {
|
||||
height:10%;
|
||||
height:8%;
|
||||
display:block;
|
||||
padding-top: 12px;
|
||||
user-select: none;
|
||||
|
||||
.pageindicators{
|
||||
text-align: center;
|
||||
position: absolute;
|
||||
right: 130px;
|
||||
left: 130px;
|
||||
bottom: 23px;
|
||||
.pageindicator {
|
||||
height: 11px;
|
||||
width: 11px;
|
||||
background: $light-medium-gray;
|
||||
border-radius: 25px;
|
||||
margin: 20px calc(3px + 0.5vw);
|
||||
display: inline-block;
|
||||
&.pageindicator--active{
|
||||
background: $green;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.modal-footer-left {
|
||||
float: left;
|
||||
text-align: left;
|
||||
width: 50%;
|
||||
height: 100%;
|
||||
.button {
|
||||
background: $light-medium-gray;
|
||||
}
|
||||
}
|
||||
|
||||
.modal-footer-right {
|
||||
|
|
@ -381,25 +459,29 @@
|
|||
width:50%;
|
||||
height:100%;
|
||||
text-align: right;
|
||||
.button {
|
||||
background: $bold-blue;
|
||||
color: white;
|
||||
}
|
||||
}
|
||||
|
||||
.button {
|
||||
border: 3px solid $black;
|
||||
border-radius: 3px;
|
||||
border-radius: 100px;
|
||||
text-align: center;
|
||||
margin: 1% auto 0;
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
font-size: calc(1vw + 20px);
|
||||
padding: 4px 10px;
|
||||
font-size: calc(0.1vw + 20px);
|
||||
padding: 7px 30px;
|
||||
border: 0px;
|
||||
a {
|
||||
color: black;
|
||||
}
|
||||
&:hover {
|
||||
background: darken($green, 20%);
|
||||
opacity:0.9;
|
||||
}
|
||||
&:active {
|
||||
background: darken($green, 35%);
|
||||
opacity:0.8;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -407,25 +489,55 @@
|
|||
.global-modal-inner {
|
||||
font-family: "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif;
|
||||
position:fixed;
|
||||
top:calc(14% - 33px);
|
||||
left:calc(15% - 33px);
|
||||
right:calc(15% - 33px);
|
||||
bottom:calc(14% - 33px);
|
||||
top:calc(9% - 36px);
|
||||
left:calc(9% - 23px);
|
||||
right:calc(9% - 23px);
|
||||
bottom:calc(5% - 33px);
|
||||
background:white;
|
||||
z-index:899902;
|
||||
text-align:center;
|
||||
font-size:calc(1.1vw + 15px);
|
||||
box-shadow:0px 0px 100px 1px rgba(0,0,0,0.3);
|
||||
border-radius:5px;
|
||||
padding:calc(1.2vw + 6px);
|
||||
padding:calc(1vw + 6px);
|
||||
h1{
|
||||
font-size:1.4em;
|
||||
font-weight:400;
|
||||
}
|
||||
@media screen and (min-width: 900px) {
|
||||
top:calc(13% - 33px);
|
||||
bottom:calc(13% - 33px);
|
||||
top:calc(7% - 33px);
|
||||
bottom:calc(7% - 33px);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
.onboarding-profile-page{
|
||||
text-align: left;
|
||||
color: $black;
|
||||
height: 70vh;
|
||||
padding-bottom: 60px;
|
||||
overflow-y: scroll;
|
||||
.onboarding-profile-question{
|
||||
font-weight: bold;
|
||||
font-size: 18px;
|
||||
padding: 12px 0px 8px;
|
||||
}
|
||||
input {
|
||||
width: 90%;
|
||||
padding: 7px;
|
||||
border-radius: 3px;
|
||||
font-size: 18px;
|
||||
border: 2px solid $light-medium-gray;
|
||||
}
|
||||
}
|
||||
|
||||
.onboarding-final-message{
|
||||
font-size: calc( 1.9vw + 2.1vh + 10px);
|
||||
font-weight: bold;
|
||||
p{
|
||||
margin: 1.2em 0px;
|
||||
}
|
||||
@media screen and (min-width: 800px) {
|
||||
font-size: 48px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -68,6 +68,9 @@ class UsersController < ApplicationController
|
|||
end
|
||||
|
||||
def onboarding_update
|
||||
if params[:user]
|
||||
current_user.update(JSON.parse(params[:user]).to_h)
|
||||
end
|
||||
current_user.saw_onboarding = true
|
||||
authorize User
|
||||
if current_user.save!
|
||||
|
|
|
|||
|
|
@ -20,9 +20,14 @@ function isUserSignedIn() {
|
|||
|
||||
function renderPage() {
|
||||
import('../src/Onboarding')
|
||||
.then(({ default: Onboarding }) =>
|
||||
render(<Onboarding />, document.getElementById('top-bar')),
|
||||
)
|
||||
.then(({ default: Onboarding }) => {
|
||||
let waitingForOnboarding = setInterval(function(){
|
||||
if (document.getElementById("main-head-stylesheet")) {
|
||||
render(<Onboarding />, document.getElementById('top-bar'))
|
||||
clearInterval(waitingForOnboarding);
|
||||
}
|
||||
}, 3)
|
||||
})
|
||||
.catch(error => {
|
||||
// eslint-disable-next-line no-console
|
||||
console.error('Unable to load onboarding', error);
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import OnboardingFollowTags from './components/OnboardingFollowTags';
|
|||
import OnboardingFollowUsers from './components/OnboardingFollowUsers';
|
||||
import OnboardingWelcomeThread from './components/OnboardingWelcomeThread';
|
||||
import cancelSvg from '../../assets/images/cancel.svg';
|
||||
import OnboardingArticles from './components/OnboardingArticles';
|
||||
import OnboardingProfile from './components/OnboardingProfile';
|
||||
|
||||
class Onboarding extends Component {
|
||||
constructor() {
|
||||
|
|
@ -20,6 +20,7 @@ class Onboarding extends Component {
|
|||
this.handleCheckUser = this.handleCheckUser.bind(this);
|
||||
this.handleSaveAllArticles = this.handleSaveAllArticles.bind(this);
|
||||
this.handleSaveArticle = this.handleSaveArticle.bind(this);
|
||||
this.handleProfileChange = this.handleProfileChange.bind(this);
|
||||
this.getUsersToFollow = this.getUsersToFollow.bind(this);
|
||||
this.state = {
|
||||
pageNumber: 1,
|
||||
|
|
@ -32,6 +33,7 @@ class Onboarding extends Component {
|
|||
articles: [],
|
||||
savedArticles: [],
|
||||
saveRequestSent: false,
|
||||
profileInfo: {}
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -154,6 +156,26 @@ class Onboarding extends Component {
|
|||
}
|
||||
}
|
||||
|
||||
handleUserProfileSave() {
|
||||
const csrfToken = document.querySelector("meta[name='csrf-token']")
|
||||
.content;
|
||||
const formData = new FormData();
|
||||
formData.append('user', JSON.stringify(this.state.profileInfo));
|
||||
|
||||
fetch('/onboarding_update', {
|
||||
method: 'PATCH',
|
||||
headers: {
|
||||
'X-CSRF-Token': csrfToken,
|
||||
},
|
||||
body: formData,
|
||||
credentials: 'same-origin',
|
||||
}).then(response => {
|
||||
if (response.ok) {
|
||||
this.setState({ saveRequestSent: true });
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
updateUserData() {
|
||||
this.setState({
|
||||
userData: JSON.parse(document.body.getAttribute('data-user')),
|
||||
|
|
@ -172,7 +194,16 @@ class Onboarding extends Component {
|
|||
formData.append('followable_type', 'Tag');
|
||||
formData.append('followable_id', tag.id);
|
||||
formData.append('verb', tag.following ? 'unfollow' : 'follow');
|
||||
|
||||
this.setState({
|
||||
allTags: this.state.allTags.map(currentTag => {
|
||||
const newTag = currentTag;
|
||||
if (currentTag.name === tag.name) {
|
||||
newTag.following = true;
|
||||
}
|
||||
return newTag;
|
||||
// add in optimistic rendering
|
||||
}),
|
||||
});
|
||||
fetch('/follows', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
|
|
@ -208,6 +239,12 @@ class Onboarding extends Component {
|
|||
}
|
||||
}
|
||||
|
||||
handleProfileChange(event) {
|
||||
let newProfileInfo = this.state.profileInfo;
|
||||
newProfileInfo[event.target.name] = event.target.value;
|
||||
this.setState({profileInfo: newProfileInfo})
|
||||
}
|
||||
|
||||
handleCheckUser(user) {
|
||||
const newCheckedUsers = this.state.checkedUsers.slice();
|
||||
if (this.state.checkedUsers.indexOf(user) > -1) {
|
||||
|
|
@ -259,14 +296,14 @@ class Onboarding extends Component {
|
|||
if (this.state.pageNumber === 4 && this.state.checkedUsers.length > 0) {
|
||||
this.handleBulkFollowUsers(this.state.checkedUsers);
|
||||
} else if (
|
||||
this.state.pageNumber === 5 &&
|
||||
this.state.savedArticles.length > 0
|
||||
this.state.pageNumber === 5
|
||||
) {
|
||||
this.handleBulkSaveArticles(this.state.savedArticles);
|
||||
this.handleUserProfileSave(this.state.profileInfo);
|
||||
}
|
||||
} else if (this.state.pageNumber === 5) {
|
||||
this.closeOnboarding();
|
||||
}
|
||||
const sloan = document.getElementById("sloan-mascot-onboarding-area");
|
||||
}
|
||||
|
||||
handleBackButton() {
|
||||
|
|
@ -325,11 +362,8 @@ class Onboarding extends Component {
|
|||
);
|
||||
} else if (this.state.pageNumber === 4) {
|
||||
return (
|
||||
<OnboardingArticles
|
||||
articles={this.state.articles}
|
||||
savedArticles={this.state.savedArticles}
|
||||
handleSaveAllArticles={this.handleSaveAllArticles}
|
||||
handleSaveArticle={this.handleSaveArticle}
|
||||
<OnboardingProfile
|
||||
onChange={this.handleProfileChange}
|
||||
/>
|
||||
);
|
||||
} else if (this.state.pageNumber === 5) {
|
||||
|
|
@ -361,13 +395,21 @@ class Onboarding extends Component {
|
|||
);
|
||||
}
|
||||
|
||||
renderPageIndicators() {
|
||||
return <div class='pageindicators'>
|
||||
<div class={this.state.pageNumber === 2 ? 'pageindicator pageindicator--active': 'pageindicator'}></div>
|
||||
<div class={this.state.pageNumber === 3 ? 'pageindicator pageindicator--active' : 'pageindicator'}></div>
|
||||
<div class={this.state.pageNumber === 4 ? 'pageindicator pageindicator--active' : 'pageindicator'}></div>
|
||||
</div>
|
||||
}
|
||||
|
||||
renderSloanMessage() {
|
||||
const messages = {
|
||||
1: 'WELCOME!',
|
||||
2: 'FOLLOW TAGS!',
|
||||
3: 'FOLLOW SOME DEVS!',
|
||||
4: 'SAVE SOME POSTS!',
|
||||
5: 'GET INVOLVED!',
|
||||
2: 'FOLLOW TAGS',
|
||||
3: 'FOLLOW DEVS',
|
||||
4: 'CREATE YOUR PROFILE',
|
||||
5: 'GET INVOLVED',
|
||||
};
|
||||
return messages[this.state.pageNumber];
|
||||
}
|
||||
|
|
@ -375,7 +417,7 @@ class Onboarding extends Component {
|
|||
render() {
|
||||
if (this.state.showOnboarding) {
|
||||
return (
|
||||
<div className="global-modal">
|
||||
<div className="global-modal" style="display:none">
|
||||
<div className="global-modal-bg">
|
||||
<button className="close-button" onClick={this.closeOnboarding}>
|
||||
<img src={cancelSvg} alt="cancel button" />
|
||||
|
|
@ -388,7 +430,7 @@ class Onboarding extends Component {
|
|||
</div>
|
||||
</div>
|
||||
<div className="modal-body">
|
||||
<div className="sloan-bar">
|
||||
<div id="sloan-mascot-onboarding-area" className="sloan-bar wiggle">
|
||||
<img
|
||||
src="https://res.cloudinary.com/practicaldev/image/fetch/s--iiubRINO--/c_imagga_scale,f_auto,fl_progressive,q_auto,w_300/https://practicaldev-herokuapp-com.freetls.fastly.net/assets/sloan.png"
|
||||
className="sloan-img"
|
||||
|
|
@ -398,7 +440,9 @@ class Onboarding extends Component {
|
|||
</div>
|
||||
<div className="modal-footer">
|
||||
<div className="modal-footer-left">{this.renderBackButton()}</div>
|
||||
<div className="modal-footer-center" />
|
||||
<div className="modal-footer-center">
|
||||
{this.renderPageIndicators()}
|
||||
</div>
|
||||
<div className="modal-footer-right">
|
||||
{this.renderNextButton()}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@ Object {
|
|||
"checkedUsers": Array [],
|
||||
"followRequestSent": false,
|
||||
"pageNumber": 1,
|
||||
"profileInfo": Object {},
|
||||
"saveRequestSent": false,
|
||||
"savedArticles": Array [],
|
||||
"showOnboarding": true,
|
||||
|
|
|
|||
26
app/javascript/src/components/OnboardingProfile.jsx
Normal file
26
app/javascript/src/components/OnboardingProfile.jsx
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
import { h, render, Component } from 'preact';
|
||||
|
||||
// page 1
|
||||
const OnboardingProfile = ({onChange}) => {
|
||||
return (
|
||||
<div class="onboarding-profile-page">
|
||||
<div className="onboarding-user-cta">
|
||||
Tell the us a bit about yourself ❤️
|
||||
</div>
|
||||
<div class="onboarding-profile-question">What's your quick bio?</div>
|
||||
<input name="summary" placeholder="e.g. I'm a passionate hacker wizard unicorn ninja" maxLength="120" onChange={onChange} />
|
||||
<div class="onboarding-profile-question">Where are you located?</div>
|
||||
<input name="location" placeholder="e.g. New York City" maxLength="60" onChange={onChange} />
|
||||
<div class="onboarding-profile-question">Where is your title?</div>
|
||||
<input name="employment_title" placeholder="e.g. Frontend developer" maxLength="60" onChange={onChange} />
|
||||
<div class="onboarding-profile-question">Where do you work?</div>
|
||||
<input name="employer_name" placeholder="e.g. Google" maxLength="60" onChange={onChange} />
|
||||
<div class="onboarding-profile-question">What are your core skills/languages?</div>
|
||||
<input name="mostly_work_with" placeholder="e.g. JavaScript and MongoDB" maxLength="200" onChange={onChange} />
|
||||
<div class="onboarding-profile-question">What are you currently learning/playing with?</div>
|
||||
<input name="currently_learning" placeholder="e.g. Rust and Docker" maxLength="200" onChange={onChange} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default OnboardingProfile;
|
||||
|
|
@ -12,20 +12,23 @@ class OnboardingSingleTag extends Component {
|
|||
}
|
||||
|
||||
render() {
|
||||
const backgroundColor = this.props.tag.following ? this.props.tag.bg_color_hex : ''
|
||||
const textroundColor = this.props.tag.following ? this.props.tag.text_color_hex : ''
|
||||
return (
|
||||
<div className={`onboarding-tag-container${this.props.tag.following ? ' followed-tag' : ''}`} id={`onboarding-tag-container-${this.props.tag.name}`} style={`background: ${this.props.tag.bg_color_hex}`}>
|
||||
<div className={`onboarding-tag-container${this.props.tag.following ? ' followed-tag' : ''}`} id={`onboarding-tag-container-${this.props.tag.name}`} style={`background: ${backgroundColor}`}>
|
||||
<a
|
||||
className="onboarding-tag-link"
|
||||
href="#"
|
||||
style={`color:${this.props.tag.text_color_hex}`}
|
||||
style={`color:${textroundColor}`}
|
||||
onClick={this.onClick}
|
||||
>
|
||||
{this.props.tag.name}
|
||||
#{this.props.tag.name}
|
||||
</a>
|
||||
<a
|
||||
className="onboarding-tag-link-follow"
|
||||
href="#"
|
||||
id={`onboarding-tag-link-follow-${this.props.tag.name}`}
|
||||
style={`color:${textroundColor}`}
|
||||
onClick={this.onClick}
|
||||
>
|
||||
{this.props.tag.following ? '✓' : '+'}
|
||||
|
|
|
|||
|
|
@ -15,9 +15,9 @@ class OnboardingTags extends Component {
|
|||
|
||||
return (
|
||||
<div className="tags-slide">
|
||||
<p>
|
||||
<strong class="yellow">What topics are you interested in?</strong> Here are a few tags to follow (There are plenty more you can choose from at any time)
|
||||
</p>
|
||||
<div className="onboarding-user-cta">
|
||||
Personalize your home feed
|
||||
</div>
|
||||
<div className="tags-col-container">
|
||||
{tags}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -20,7 +20,8 @@ class OnboardingUsers extends Component {
|
|||
src={user.profile_image_url}
|
||||
alt={user.name}
|
||||
/>
|
||||
{user.name}
|
||||
<div>{user.name}</div>
|
||||
<div className="onboarding-user-list-row__summary"><em>{user.summary}</em></div>
|
||||
</div>
|
||||
<div className="onboarding-user-list-checkbox">
|
||||
<button onClick={this.props.handleCheckUser.bind(this, user)} className={this.props.checkedUsers.indexOf(user) > -1 ? 'checked' : ''}>
|
||||
|
|
@ -44,10 +45,10 @@ class OnboardingUsers extends Component {
|
|||
return (
|
||||
<div className="onboarding-user-container">
|
||||
<div className="onboarding-user-cta">
|
||||
Here are some folks from the community you might want to follow <strong className="yellow">based on your interests.</strong>
|
||||
Here are some suggestions based on your interests
|
||||
</div>
|
||||
<div className="onboarding-user-list">
|
||||
<div className="onboarding-user-list-header onboarding-user-list-row">
|
||||
<div className="onboarding-user-list-header">
|
||||
<div className="onboarding-user-list-key">
|
||||
Follow All
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -3,17 +3,16 @@ import { h, render, Component } from 'preact';
|
|||
// page 1
|
||||
const OnboardingWelcome = () => {
|
||||
const messages = [
|
||||
"Hi there, I'm Sloan. It's nice to meet you!",
|
||||
"Welcome to the community. It's a place to talk shop and keep up with other devs.",
|
||||
"Share more, learn more, write better code; I think you'll like it here. 🐨",
|
||||
"Thank you for joining the DEV Community.",
|
||||
"Keep up with the people and software trends you care about. ❤️",
|
||||
];
|
||||
|
||||
const specialMessage = "Let's get started";
|
||||
const specialMessage = "Let's get started!";
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div class="onboarding-initial-welcome">
|
||||
{messages.map(item => (<p>{item}</p>))}
|
||||
<p><strong className="yellow">{specialMessage}.</strong></p>
|
||||
<p><em><strong className="green">{specialMessage}</strong></em></p>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -6,12 +6,10 @@ const OnboardingWelcomeThread = () => {
|
|||
);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<p>Got a question? {wrapInYellow('Start a discussion')}.</p>
|
||||
<p>Got a blog post? {wrapInYellow('Publish it')}.</p>
|
||||
<p>Not sure what to say? {wrapInYellow('Fill out your profile')} or just poke around and read.</p>
|
||||
<p>Like something you read? {wrapInYellow('Follow the author')} for more from them.</p>
|
||||
<p>See you around! <span role="img" aria-label="Victory hand">✌️</span> </p>
|
||||
<div class="onboarding-final-message">
|
||||
<p>Software is driven by community.</p>
|
||||
<p>Don't hesitate to find a discussion and jump right in.</p>
|
||||
<p><em class="green">Everyone is welcome!</em></p>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -16,11 +16,11 @@ describe('<OnboardingSingleTag />', () => {
|
|||
it('responses to clicks', () => {
|
||||
const onClick = jest.fn();
|
||||
const context = shallow(<OnboardingSingleTag tag={followingTag} onTagClick={onClick} />);
|
||||
expect(context.find('a').text()).toEqual('✓');
|
||||
expect(context.find('a').text()).toEqual('#✓');
|
||||
context.find('.onboarding-tag-link-follow').simulate('click');
|
||||
expect(onClick).toHaveBeenCalledTimes(1);
|
||||
context.render(<OnboardingSingleTag tag={notFollowingTag} onTagClick={onClick} />);
|
||||
expect(context.find('a').text()).toEqual('+');
|
||||
expect(context.find('a').text()).toEqual('#+');
|
||||
});
|
||||
});
|
||||
|
||||
|
|
@ -33,11 +33,11 @@ describe('<OnboardingSingleTag />', () => {
|
|||
it('responses to clicks', () => {
|
||||
const onClick = jest.fn();
|
||||
const context = shallow(<OnboardingSingleTag tag={notFollowingTag} onTagClick={onClick} />);
|
||||
expect(context.find('a').text()).toEqual('+');
|
||||
expect(context.find('a').text()).toEqual('#+');
|
||||
context.find('.onboarding-tag-link-follow').simulate('click');
|
||||
expect(onClick).toHaveBeenCalledTimes(1);
|
||||
context.render(<OnboardingSingleTag tag={followingTag} onTagClick={onClick} />);
|
||||
expect(context.find('a').text()).toEqual('✓');
|
||||
expect(context.find('a').text()).toEqual('#✓');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -4,35 +4,33 @@ exports[`<OnboardingFollowTags /> renders properly when given a tag 1`] = `
|
|||
<div
|
||||
class="tags-slide"
|
||||
>
|
||||
<p>
|
||||
<strong
|
||||
class="yellow"
|
||||
>
|
||||
What topics are you interested in?
|
||||
</strong>
|
||||
Here are a few tags to follow (There are plenty more you can choose from at any time)
|
||||
</p>
|
||||
<div
|
||||
class="onboarding-user-cta"
|
||||
>
|
||||
Personalize your home feed
|
||||
</div>
|
||||
<div
|
||||
class="tags-col-container"
|
||||
>
|
||||
<div
|
||||
class="onboarding-tag-container"
|
||||
id="onboarding-tag-container-discuss"
|
||||
style="background: #000000"
|
||||
style="background: "
|
||||
>
|
||||
<a
|
||||
class="onboarding-tag-link"
|
||||
href="#"
|
||||
onClick={[Function]}
|
||||
style="color:#ffffff"
|
||||
style="color:"
|
||||
>
|
||||
discuss
|
||||
#discuss
|
||||
</a>
|
||||
<a
|
||||
class="onboarding-tag-link-follow"
|
||||
href="#"
|
||||
id="onboarding-tag-link-follow-discuss"
|
||||
onClick={[Function]}
|
||||
style="color:"
|
||||
>
|
||||
+
|
||||
</a>
|
||||
|
|
@ -40,21 +38,22 @@ exports[`<OnboardingFollowTags /> renders properly when given a tag 1`] = `
|
|||
<div
|
||||
class="onboarding-tag-container"
|
||||
id="onboarding-tag-container-javascript"
|
||||
style="background: #f7df1e"
|
||||
style="background: "
|
||||
>
|
||||
<a
|
||||
class="onboarding-tag-link"
|
||||
href="#"
|
||||
onClick={[Function]}
|
||||
style="color:#000000"
|
||||
style="color:"
|
||||
>
|
||||
javascript
|
||||
#javascript
|
||||
</a>
|
||||
<a
|
||||
class="onboarding-tag-link-follow"
|
||||
href="#"
|
||||
id="onboarding-tag-link-follow-javascript"
|
||||
onClick={[Function]}
|
||||
style="color:"
|
||||
>
|
||||
+
|
||||
</a>
|
||||
|
|
@ -62,21 +61,22 @@ exports[`<OnboardingFollowTags /> renders properly when given a tag 1`] = `
|
|||
<div
|
||||
class="onboarding-tag-container"
|
||||
id="onboarding-tag-container-javascript"
|
||||
style="background: #f7df1e"
|
||||
style="background: "
|
||||
>
|
||||
<a
|
||||
class="onboarding-tag-link"
|
||||
href="#"
|
||||
onClick={[Function]}
|
||||
style="color:#000000"
|
||||
style="color:"
|
||||
>
|
||||
javascript
|
||||
#javascript
|
||||
</a>
|
||||
<a
|
||||
class="onboarding-tag-link-follow"
|
||||
href="#"
|
||||
id="onboarding-tag-link-follow-javascript"
|
||||
onClick={[Function]}
|
||||
style="color:"
|
||||
>
|
||||
+
|
||||
</a>
|
||||
|
|
|
|||
|
|
@ -7,18 +7,13 @@ exports[`<OnboardingFollowUsers /> renders properly when given users 1`] = `
|
|||
<div
|
||||
class="onboarding-user-cta"
|
||||
>
|
||||
Here are some folks from the community you might want to follow
|
||||
<strong
|
||||
class="yellow"
|
||||
>
|
||||
based on your interests.
|
||||
</strong>
|
||||
Here are some suggestions based on your interests
|
||||
</div>
|
||||
<div
|
||||
class="onboarding-user-list"
|
||||
>
|
||||
<div
|
||||
class="onboarding-user-list-header onboarding-user-list-row"
|
||||
class="onboarding-user-list-header"
|
||||
>
|
||||
<div
|
||||
class="onboarding-user-list-key"
|
||||
|
|
@ -50,7 +45,14 @@ exports[`<OnboardingFollowUsers /> renders properly when given users 1`] = `
|
|||
alt="Ben Halpern"
|
||||
src="ben.jpg"
|
||||
/>
|
||||
Ben Halpern
|
||||
<div>
|
||||
Ben Halpern
|
||||
</div>
|
||||
<div
|
||||
class="onboarding-user-list-row__summary"
|
||||
>
|
||||
<em />
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="onboarding-user-list-checkbox"
|
||||
|
|
@ -72,7 +74,14 @@ exports[`<OnboardingFollowUsers /> renders properly when given users 1`] = `
|
|||
alt="Krusty the Clown"
|
||||
src="clown.jpg"
|
||||
/>
|
||||
Krusty the Clown
|
||||
<div>
|
||||
Krusty the Clown
|
||||
</div>
|
||||
<div
|
||||
class="onboarding-user-list-row__summary"
|
||||
>
|
||||
<em />
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="onboarding-user-list-checkbox"
|
||||
|
|
@ -94,7 +103,14 @@ exports[`<OnboardingFollowUsers /> renders properly when given users 1`] = `
|
|||
alt="dev.to staff"
|
||||
src="dev.jpg"
|
||||
/>
|
||||
dev.to staff
|
||||
<div>
|
||||
dev.to staff
|
||||
</div>
|
||||
<div
|
||||
class="onboarding-user-list-row__summary"
|
||||
>
|
||||
<em />
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="onboarding-user-list-checkbox"
|
||||
|
|
|
|||
|
|
@ -11,12 +11,15 @@ exports[`<OnboardingSingleTag /> when given a following tag renders correctly 1`
|
|||
href="#"
|
||||
onClick={[Function]}
|
||||
style="color:undefined"
|
||||
/>
|
||||
>
|
||||
#
|
||||
</a>
|
||||
<a
|
||||
class="onboarding-tag-link-follow"
|
||||
href="#"
|
||||
id="onboarding-tag-link-follow-undefined"
|
||||
onClick={[Function]}
|
||||
style="color:undefined"
|
||||
>
|
||||
✓
|
||||
</a>
|
||||
|
|
@ -27,19 +30,22 @@ exports[`<OnboardingSingleTag /> when given a non-following tag renders correctl
|
|||
<div
|
||||
class="onboarding-tag-container"
|
||||
id="onboarding-tag-container-undefined"
|
||||
style="background: undefined"
|
||||
style="background: "
|
||||
>
|
||||
<a
|
||||
class="onboarding-tag-link"
|
||||
href="#"
|
||||
onClick={[Function]}
|
||||
style="color:undefined"
|
||||
/>
|
||||
style="color:"
|
||||
>
|
||||
#
|
||||
</a>
|
||||
<a
|
||||
class="onboarding-tag-link-follow"
|
||||
href="#"
|
||||
id="onboarding-tag-link-follow-undefined"
|
||||
onClick={[Function]}
|
||||
style="color:"
|
||||
>
|
||||
+
|
||||
</a>
|
||||
|
|
|
|||
|
|
@ -7,18 +7,13 @@ exports[`<OnboardingUsers /> when given users to follow renders correctly 1`] =
|
|||
<div
|
||||
class="onboarding-user-cta"
|
||||
>
|
||||
Here are some folks from the community you might want to follow
|
||||
<strong
|
||||
class="yellow"
|
||||
>
|
||||
based on your interests.
|
||||
</strong>
|
||||
Here are some suggestions based on your interests
|
||||
</div>
|
||||
<div
|
||||
class="onboarding-user-list"
|
||||
>
|
||||
<div
|
||||
class="onboarding-user-list-header onboarding-user-list-row"
|
||||
class="onboarding-user-list-header"
|
||||
>
|
||||
<div
|
||||
class="onboarding-user-list-key"
|
||||
|
|
@ -50,7 +45,14 @@ exports[`<OnboardingUsers /> when given users to follow renders correctly 1`] =
|
|||
alt="Ben Halpern"
|
||||
src="ben.jpg"
|
||||
/>
|
||||
Ben Halpern
|
||||
<div>
|
||||
Ben Halpern
|
||||
</div>
|
||||
<div
|
||||
class="onboarding-user-list-row__summary"
|
||||
>
|
||||
<em />
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="onboarding-user-list-checkbox"
|
||||
|
|
@ -72,7 +74,14 @@ exports[`<OnboardingUsers /> when given users to follow renders correctly 1`] =
|
|||
alt="Krusty the Clown"
|
||||
src="clown.jpg"
|
||||
/>
|
||||
Krusty the Clown
|
||||
<div>
|
||||
Krusty the Clown
|
||||
</div>
|
||||
<div
|
||||
class="onboarding-user-list-row__summary"
|
||||
>
|
||||
<em />
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="onboarding-user-list-checkbox"
|
||||
|
|
@ -94,7 +103,14 @@ exports[`<OnboardingUsers /> when given users to follow renders correctly 1`] =
|
|||
alt="dev.to staff"
|
||||
src="dev.jpg"
|
||||
/>
|
||||
dev.to staff
|
||||
<div>
|
||||
dev.to staff
|
||||
</div>
|
||||
<div
|
||||
class="onboarding-user-list-row__summary"
|
||||
>
|
||||
<em />
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="onboarding-user-list-checkbox"
|
||||
|
|
|
|||
|
|
@ -1,22 +1,23 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`<OnboardingWelcome /> renders correctly 1`] = `
|
||||
<div>
|
||||
<div
|
||||
class="onboarding-initial-welcome"
|
||||
>
|
||||
<p>
|
||||
Hi there, I'm Sloan. It's nice to meet you!
|
||||
Thank you for joining the DEV Community.
|
||||
</p>
|
||||
<p>
|
||||
Welcome to the community. It's a place to talk shop and keep up with other devs.
|
||||
Keep up with the people and software trends you care about. ❤️
|
||||
</p>
|
||||
<p>
|
||||
Share more, learn more, write better code; I think you'll like it here. 🐨
|
||||
</p>
|
||||
<p>
|
||||
<strong
|
||||
class="yellow"
|
||||
>
|
||||
Let's get started.
|
||||
</strong>
|
||||
<em>
|
||||
<strong
|
||||
class="green"
|
||||
>
|
||||
Let's get started!
|
||||
</strong>
|
||||
</em>
|
||||
</p>
|
||||
</div>
|
||||
`;
|
||||
|
|
|
|||
|
|
@ -1,52 +1,21 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`<OnboardingWelcomeThread /> renders correctly 1`] = `
|
||||
<div>
|
||||
<div
|
||||
class="onboarding-final-message"
|
||||
>
|
||||
<p>
|
||||
Got a question?
|
||||
<strong
|
||||
class="yellow"
|
||||
>
|
||||
Start a discussion
|
||||
</strong>
|
||||
.
|
||||
Software is driven by community.
|
||||
</p>
|
||||
<p>
|
||||
Got a blog post?
|
||||
<strong
|
||||
class="yellow"
|
||||
>
|
||||
Publish it
|
||||
</strong>
|
||||
.
|
||||
Don't hesitate to find a discussion and jump right in.
|
||||
</p>
|
||||
<p>
|
||||
Not sure what to say?
|
||||
<strong
|
||||
class="yellow"
|
||||
<em
|
||||
class="green"
|
||||
>
|
||||
Fill out your profile
|
||||
</strong>
|
||||
or just poke around and read.
|
||||
</p>
|
||||
<p>
|
||||
Like something you read?
|
||||
<strong
|
||||
class="yellow"
|
||||
>
|
||||
Follow the author
|
||||
</strong>
|
||||
for more from them.
|
||||
</p>
|
||||
<p>
|
||||
See you around!
|
||||
<span
|
||||
aria-label="Victory hand"
|
||||
role="img"
|
||||
>
|
||||
✌️
|
||||
</span>
|
||||
|
||||
Everyone is welcome!
|
||||
</em>
|
||||
</p>
|
||||
</div>
|
||||
`;
|
||||
|
|
|
|||
|
|
@ -4,10 +4,11 @@ class Tag < ActsAsTaggableOn::Tag
|
|||
resourcify
|
||||
|
||||
NAMES = %w(
|
||||
beginners career computerscience git go java javascript
|
||||
beginners career computerscience git go java javascript react vue
|
||||
linux productivity python security webdev css php opensource
|
||||
ruby cpp dotnet swift testing devops vim kotlin rust elixir
|
||||
scala
|
||||
scala vscode docker aws android ios angular csharp typescript django rails
|
||||
clojure ubuntu elm gamedev flutter bash
|
||||
).freeze
|
||||
|
||||
mount_uploader :profile_image, ProfileImageUploader
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ json.array! @users.each do |user|
|
|||
json.id user.id
|
||||
json.name user.name
|
||||
json.username user.username
|
||||
json.summary truncate(user.summary.present? ? user.summary : "Active DEV author" , length: 100)
|
||||
json.profile_image_url ProfileImage.new(user).get(90)
|
||||
json.following false
|
||||
end
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue