mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-11-25 09:03:12 +03:00
🎨 User profile settings page layout updates (#695)
closes TryGhost/Ghost#7134 Overhaul of the user settings page to make it more consistent with other settings panels. The hardly readable validation for user "Full Name" is redundant as well, as the input field for it now has the same styles as the other input fields.
This commit is contained in:
parent
fed5dc8a79
commit
67ded0c8ed
@ -16,9 +16,9 @@ export function countCharacters(params) {
|
|||||||
el.className = 'word-count';
|
el.className = 'word-count';
|
||||||
|
|
||||||
if (length > 180) {
|
if (length > 180) {
|
||||||
el.style.color = '#E25440';
|
el.style.color = '#f05230';
|
||||||
} else {
|
} else {
|
||||||
el.style.color = '#9E9D95';
|
el.style.color = '#738a94';
|
||||||
}
|
}
|
||||||
|
|
||||||
el.innerHTML = 200 - length;
|
el.innerHTML = 200 - length;
|
||||||
|
@ -39,37 +39,16 @@
|
|||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (min-width: 901px) {
|
|
||||||
.content.settings-user {
|
|
||||||
padding: 0 40px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.user-cover {
|
.user-cover {
|
||||||
position: relative;
|
display: block;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
width: auto;
|
width: 100%;
|
||||||
height: 300px;
|
height: 300px;
|
||||||
|
margin-bottom: 30px;
|
||||||
background: #fafafa no-repeat center center;
|
background: #fafafa no-repeat center center;
|
||||||
background-size: cover;
|
background-size: cover;
|
||||||
}
|
border-radius: 6px;
|
||||||
|
|
||||||
@media (max-width: 900px) {
|
|
||||||
.user-cover {
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.user-cover:after {
|
|
||||||
/* Gradient overlay */
|
|
||||||
content: "";
|
|
||||||
position: absolute;
|
|
||||||
right: 0;
|
|
||||||
bottom: 0;
|
|
||||||
left: 0;
|
|
||||||
height: 110px;
|
|
||||||
background: linear-gradient(transparent, rgba(0, 0, 0, 0.18));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.user-cover-edit {
|
.user-cover-edit {
|
||||||
@ -96,62 +75,11 @@
|
|||||||
/* Edit user
|
/* Edit user
|
||||||
/* ---------------------------------------------------------- */
|
/* ---------------------------------------------------------- */
|
||||||
|
|
||||||
@media (min-width: 651px) {
|
|
||||||
.first-form-group {
|
|
||||||
margin-right: 20px;
|
|
||||||
padding-left: 40px;
|
|
||||||
}
|
|
||||||
.first-form-group input {
|
|
||||||
max-width: 100%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.user-details-top {
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 650px) {
|
|
||||||
.user-details-top {
|
|
||||||
margin-top: 40px;
|
|
||||||
margin-bottom: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (min-width: 651px) {
|
|
||||||
.user-details-top {
|
|
||||||
margin-top: -91px;
|
|
||||||
margin-bottom: 0;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
.user-details-top p {
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
.user-details-top label[for="user-name"] {
|
|
||||||
color: transparent;
|
|
||||||
}
|
|
||||||
.user-details-top .user-name {
|
|
||||||
border-color: #fff;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.user-profile {
|
.user-profile {
|
||||||
position: relative;
|
position: relative;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (min-width: 651px) {
|
|
||||||
.user-profile {
|
|
||||||
padding-right: 20px;
|
|
||||||
padding-left: 143px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 650px) {
|
|
||||||
.user-profile fieldset {
|
|
||||||
padding: 0 40px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 550px) {
|
@media (max-width: 550px) {
|
||||||
.user-profile fieldset {
|
.user-profile fieldset {
|
||||||
padding: 0 15px;
|
padding: 0 15px;
|
||||||
@ -159,7 +87,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.user-profile textarea {
|
.user-profile textarea {
|
||||||
min-width: 240px;
|
min-width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -168,43 +96,24 @@
|
|||||||
|
|
||||||
.user-image {
|
.user-image {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
top: 200px;
|
||||||
|
left: 0;
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
display: block;
|
margin: 0;
|
||||||
float: left;
|
padding: 0;
|
||||||
overflow: hidden;
|
width: 100px;
|
||||||
margin-right: 20px;
|
height: 100px;
|
||||||
margin-left: -6px;
|
border-radius: 0 6px;
|
||||||
padding: 3px;
|
|
||||||
width: 126px;
|
|
||||||
height: 126px;
|
|
||||||
background: #fff;
|
|
||||||
border-radius: 100%;
|
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (min-width: 651px) {
|
|
||||||
.user-image {
|
|
||||||
top: -19px;
|
|
||||||
left: -98px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 650px) {
|
|
||||||
.user-image {
|
|
||||||
top: -135px;
|
|
||||||
left: 50%;
|
|
||||||
margin-right: 0;
|
|
||||||
margin-left: -63px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.user-image .img {
|
.user-image .img {
|
||||||
display: block;
|
display: block;
|
||||||
width: 120px;
|
width: 100%;
|
||||||
height: 120px;
|
height: 100%;
|
||||||
background-position: center center;
|
background-position: center center;
|
||||||
background-size: cover;
|
background-size: cover;
|
||||||
border-radius: 100%;
|
border-radius: 0 6px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.user-image:hover .edit-user-image {
|
.user-image:hover .edit-user-image {
|
||||||
@ -213,17 +122,16 @@
|
|||||||
|
|
||||||
.edit-user-image {
|
.edit-user-image {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 3px;
|
top: 0;
|
||||||
right: 3px;
|
left: 0;
|
||||||
bottom: 3px;
|
width: 100%;
|
||||||
left: 3px;
|
|
||||||
width: calc(100% - 6px);
|
|
||||||
background: rgba(0, 0, 0, 0.5);
|
background: rgba(0, 0, 0, 0.5);
|
||||||
border-radius: 100%;
|
border-radius: 0 6px;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
line-height: 120px;
|
font-size: 12px;
|
||||||
|
line-height: 100px;
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
transition: opacity 0.3s ease;
|
transition: opacity 0.3s ease;
|
||||||
}
|
}
|
||||||
|
@ -84,171 +84,165 @@
|
|||||||
</section>
|
</section>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<div class="view-container settings-user">
|
<div class="gm-main view-container settings-user">
|
||||||
|
<div class="gh-canvas">
|
||||||
|
<form class="user-profile" novalidate="novalidate" autocomplete="off" {{action (perform save) on="submit"}}>
|
||||||
|
|
||||||
<figure class="user-cover" style={{coverImageBackground}}>
|
<figure class="user-cover" style={{coverImageBackground}}>
|
||||||
<button class="gh-btn gh-btn-default user-cover-edit" {{action "toggleUploadCoverModal"}}><span>Change Cover</span></button>
|
<button class="gh-btn gh-btn-default user-cover-edit" {{action "toggleUploadCoverModal"}}><span>Change Cover</span></button>
|
||||||
{{#if showUploadCoverModal}}
|
{{#if showUploadCoverModal}}
|
||||||
{{gh-fullscreen-modal "upload-image"
|
{{gh-fullscreen-modal "upload-image"
|
||||||
model=(hash model=user imageProperty="coverImage")
|
model=(hash model=user imageProperty="cover")
|
||||||
close=(action "toggleUploadCoverModal")
|
close=(action "toggleUploadCoverModal")
|
||||||
modifier="action wide"}}
|
modifier="action wide"}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</figure>
|
</figure>
|
||||||
|
|
||||||
<form class="user-profile" novalidate="novalidate" autocomplete="off" {{action (perform save) on="submit"}}>
|
<figure class="user-image">
|
||||||
|
<div id="user-image" class="img" style={{userImageBackground}}><span class="hidden">{{user.name}}"s Picture</span></div>
|
||||||
|
<button type="button" {{action "toggleUploadImageModal"}} class="edit-user-image">Edit Picture</button>
|
||||||
|
{{#if showUploadImageModal}}
|
||||||
|
{{gh-fullscreen-modal "upload-image"
|
||||||
|
model=(hash model=user imageProperty="image")
|
||||||
|
close=(action "toggleUploadImageModal")
|
||||||
|
modifier="action wide"}}
|
||||||
|
{{/if}}
|
||||||
|
</figure>
|
||||||
|
|
||||||
{{!-- Horrible hack to prevent Chrome from incorrectly auto-filling inputs --}}
|
{{!-- Horrible hack to prevent Chrome from incorrectly auto-filling inputs --}}
|
||||||
<input style="display:none;" type="text" name="fakeusernameremembered"/>
|
<input style="display:none;" type="text" name="fakeusernameremembered"/>
|
||||||
<input style="display:none;" type="password" name="fakepasswordremembered"/>
|
<input style="display:none;" type="password" name="fakepasswordremembered"/>
|
||||||
|
|
||||||
<fieldset class="user-details-top">
|
<fieldset class="user-details-bottom">
|
||||||
|
|
||||||
<figure class="user-image">
|
{{#gh-form-group errors=user.errors hasValidated=user.hasValidated property="name" class="first-form-group"}}
|
||||||
<div id="user-image" class="img" style={{userImageBackground}}><span class="hidden">{{user.name}}"s Picture</span></div>
|
<label for="user-name">Full Name</label>
|
||||||
<button type="button" {{action "toggleUploadImageModal"}} class="edit-user-image">Edit Picture</button>
|
{{gh-input user.name id="user-name" class="user-name" placeholder="Full Name" autocorrect="off" focusOut=(action "validate" "name" target=user) update=(action (mut user.name))}}
|
||||||
{{#if showUploadImageModal}}
|
{{#if user.errors.name}}
|
||||||
{{gh-fullscreen-modal "upload-image"
|
{{gh-error-message errors=user.errors property="name"}}
|
||||||
model=(hash model=user imageProperty="profileImage")
|
{{else}}
|
||||||
close=(action "toggleUploadImageModal")
|
<p>Use your real name so people can recognise you</p>
|
||||||
modifier="action wide"}}
|
{{/if}}
|
||||||
{{/if}}
|
|
||||||
</figure>
|
|
||||||
|
|
||||||
{{#gh-form-group errors=user.errors hasValidated=user.hasValidated property="name" class="first-form-group"}}
|
|
||||||
<label for="user-name">Full Name</label>
|
|
||||||
{{gh-input user.name id="user-name" class="user-name" placeholder="Full Name" autocorrect="off" focusOut=(action "validate" "name" target=user) update=(action (mut user.name))}}
|
|
||||||
{{#if user.errors.name}}
|
|
||||||
{{gh-error-message errors=user.errors property="name"}}
|
|
||||||
{{else}}
|
|
||||||
<p>Use your real name so people can recognise you</p>
|
|
||||||
{{/if}}
|
|
||||||
{{/gh-form-group}}
|
|
||||||
|
|
||||||
</fieldset>
|
|
||||||
|
|
||||||
<fieldset class="user-details-bottom">
|
|
||||||
|
|
||||||
{{#gh-form-group errors=user.errors hasValidated=user.hasValidated property="slug"}}
|
|
||||||
<label for="user-slug">Slug</label>
|
|
||||||
{{gh-input slugValue class="user-name" id="user-slug" name="user" focusOut=(action (perform updateSlug slugValue)) placeholder="Slug" selectOnClick="true" autocorrect="off" update=(action (mut slugValue))}}
|
|
||||||
<p>{{gh-blog-url}}/author/{{slugValue}}</p>
|
|
||||||
{{gh-error-message errors=user.errors property="slug"}}
|
|
||||||
{{/gh-form-group}}
|
|
||||||
|
|
||||||
{{#gh-form-group errors=user.errors hasValidated=user.hasValidated property="email"}}
|
|
||||||
<label for="user-email">Email</label>
|
|
||||||
{{!-- Administrators only see text of Owner's email address but not input --}}
|
|
||||||
{{#if canChangeEmail}}
|
|
||||||
{{gh-input user.email type="email" id="user-email" name="email" placeholder="Email Address" autocapitalize="off" autocorrect="off" autocomplete="off" focusOut=(action "validate" "email" target=user) update=(action (mut user.email))}}
|
|
||||||
{{gh-error-message errors=user.errors property="email"}}
|
|
||||||
{{else}}
|
|
||||||
<span>{{user.email}}</span>
|
|
||||||
{{/if}}
|
|
||||||
<p>Used for notifications</p>
|
|
||||||
{{/gh-form-group}}
|
|
||||||
|
|
||||||
{{#if rolesDropdownIsVisible}}
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="user-role">Role</label>
|
|
||||||
<span class="gh-select" tabindex="0">
|
|
||||||
{{one-way-select
|
|
||||||
id="new-user-role"
|
|
||||||
options=roles
|
|
||||||
optionValuePath="id"
|
|
||||||
optionLabelPath="name"
|
|
||||||
value=model.role
|
|
||||||
update=(action "changeRole")
|
|
||||||
}}
|
|
||||||
{{inline-svg "arrow-down-small"}}
|
|
||||||
</span>
|
|
||||||
<p>What permissions should this user have?</p>
|
|
||||||
</div>
|
|
||||||
{{/if}}
|
|
||||||
|
|
||||||
{{#gh-form-group errors=user.errors hasValidated=user.hasValidated property="location"}}
|
|
||||||
<label for="user-location">Location</label>
|
|
||||||
{{gh-input user.location type="text" id="user-location" focusOut=(action "validate" "location" target=user) update=(action (mut user.location))}}
|
|
||||||
{{gh-error-message errors=user.errors property="location"}}
|
|
||||||
<p>Where in the world do you live?</p>
|
|
||||||
{{/gh-form-group}}
|
|
||||||
|
|
||||||
{{#gh-form-group errors=user.errors hasValidated=user.hasValidated property="website"}}
|
|
||||||
<label for="user-website">Website</label>
|
|
||||||
{{gh-input user.website type="url" id="user-website" autocapitalize="off" autocorrect="off" autocomplete="off" focusOut=(action "validate" "website" target=user) update=(action (mut user.website))}}
|
|
||||||
{{gh-error-message errors=user.errors property="website"}}
|
|
||||||
<p>Have a website or blog other than this one? Link it!</p>
|
|
||||||
{{/gh-form-group}}
|
|
||||||
|
|
||||||
{{#gh-form-group errors=user.errors hasValidated=user.hasValidated property="facebook"}}
|
|
||||||
<label for="user-facebook">Facebook Profile</label>
|
|
||||||
<input value={{user.facebook}} oninput={{action (mut _scratchFacebook) value="target.value"}} {{action "validateFacebookUrl" on="focusOut"}} type="url" class="gh-input" id="user-facebook" name="user[facebook]" placeholder="https://www.facebook.com/username" autocorrect="off" />
|
|
||||||
{{gh-error-message errors=user.errors property="facebook"}}
|
|
||||||
<p>URL of your personal Facebook Profile</p>
|
|
||||||
{{/gh-form-group}}
|
|
||||||
|
|
||||||
{{#gh-form-group errors=user.errors hasValidated=user.hasValidated property="twitter"}}
|
|
||||||
<label for="user-twitter">Twitter Profile</label>
|
|
||||||
<input value={{user.twitter}} oninput={{action (mut _scratchTwitter) value="target.value"}} {{action "validateTwitterUrl" on="focusOut"}} type="url" class="gh-input" id="user-twitter" name="user[twitter]" placeholder="https://twitter.com/username" autocorrect="off" />
|
|
||||||
{{gh-error-message errors=user.errors property="twitter"}}
|
|
||||||
<p>URL of your personal Twitter profile</p>
|
|
||||||
{{/gh-form-group}}
|
|
||||||
|
|
||||||
{{#gh-form-group errors=user.errors hasValidated=user.hasValidated property="bio" class="bio-container"}}
|
|
||||||
<label for="user-bio">Bio</label>
|
|
||||||
{{gh-textarea user.bio id="user-bio" focusOut=(action "validate" "bio" target=user) update=(action (mut user.bio))}}
|
|
||||||
{{gh-error-message errors=user.errors property="bio"}}
|
|
||||||
<p>
|
|
||||||
Write about you, in 200 characters or less.
|
|
||||||
{{gh-count-characters user.bio}}
|
|
||||||
</p>
|
|
||||||
{{/gh-form-group}}
|
|
||||||
|
|
||||||
<hr />
|
|
||||||
|
|
||||||
</fieldset>
|
|
||||||
|
|
||||||
</form> {{! user details form }}
|
|
||||||
|
|
||||||
{{!-- If an administrator is viewing Owner's profile or we're using Ghost.org OAuth then hide inputs for change password --}}
|
|
||||||
{{#if canChangePassword}}
|
|
||||||
<form id="password-reset" class="user-profile" novalidate="novalidate" autocomplete="off" {{action (perform user.saveNewPassword) on="submit"}}>
|
|
||||||
<fieldset>
|
|
||||||
{{#unless isNotOwnProfile}}
|
|
||||||
{{#gh-form-group errors=user.errors hasValidated=user.hasValidated property="password"}}
|
|
||||||
<label for="user-password-old">Old Password</label>
|
|
||||||
{{gh-input value=user.password type="password" id="user-password-old" update=(action 'updatePassword') onenter=(action (perform user.saveNewPassword))}}
|
|
||||||
{{gh-error-message errors=user.errors property="password"}}
|
|
||||||
{{/gh-form-group}}
|
|
||||||
{{/unless}}
|
|
||||||
|
|
||||||
{{#gh-form-group errors=user.errors hasValidated=user.hasValidated property="newPassword"}}
|
|
||||||
<label for="user-password-new">New Password</label>
|
|
||||||
{{gh-input user.newPassword type="password" id="user-password-new" update=(action 'updateNewPassword') onenter=(action (perform user.saveNewPassword))}}
|
|
||||||
{{gh-error-message errors=user.errors property="newPassword"}}
|
|
||||||
{{/gh-form-group}}
|
{{/gh-form-group}}
|
||||||
|
|
||||||
{{#gh-form-group errors=user.errors hasValidated=user.hasValidated property="ne2Password"}}
|
{{#gh-form-group errors=user.errors hasValidated=user.hasValidated property="slug"}}
|
||||||
<label for="user-new-password-verification">Verify Password</label>
|
<label for="user-slug">Slug</label>
|
||||||
{{gh-input user.ne2Password type="password" id="user-new-password-verification" update=(action 'updateNe2Password') onenter=(action (perform user.saveNewPassword))}}
|
{{gh-input slugValue class="user-name" id="user-slug" name="user" focusOut=(action (perform updateSlug slugValue)) placeholder="Slug" selectOnClick="true" autocorrect="off" update=(action (mut slugValue))}}
|
||||||
{{gh-error-message errors=user.errors property="ne2Password"}}
|
<p>{{gh-blog-url}}/author/{{slugValue}}</p>
|
||||||
|
{{gh-error-message errors=user.errors property="slug"}}
|
||||||
{{/gh-form-group}}
|
{{/gh-form-group}}
|
||||||
|
|
||||||
<div class="form-group">
|
{{#gh-form-group errors=user.errors hasValidated=user.hasValidated property="email"}}
|
||||||
{{gh-task-button "Change Password"
|
<label for="user-email">Email</label>
|
||||||
class="gh-btn gh-btn-icon button-change-password"
|
{{!-- Administrators only see text of Owner's email address but not input --}}
|
||||||
idleClass="gh-btn-red"
|
{{#if canChangeEmail}}
|
||||||
task=user.saveNewPassword}}
|
{{gh-input user.email type="email" id="user-email" name="email" placeholder="Email Address" autocapitalize="off" autocorrect="off" autocomplete="off" focusOut=(action "validate" "email" target=user) update=(action (mut user.email))}}
|
||||||
</div>
|
{{gh-error-message errors=user.errors property="email"}}
|
||||||
|
{{else}}
|
||||||
|
<span>{{user.email}}</span>
|
||||||
|
{{/if}}
|
||||||
|
<p>Used for notifications</p>
|
||||||
|
{{/gh-form-group}}
|
||||||
|
|
||||||
|
{{#if rolesDropdownIsVisible}}
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="user-role">Role</label>
|
||||||
|
<span class="gh-select" tabindex="0">
|
||||||
|
{{one-way-select
|
||||||
|
id="new-user-role"
|
||||||
|
options=roles
|
||||||
|
optionValuePath="id"
|
||||||
|
optionLabelPath="name"
|
||||||
|
value=model.role
|
||||||
|
update=(action "changeRole")
|
||||||
|
}}
|
||||||
|
</span>
|
||||||
|
<p>What permissions should this user have?</p>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
{{#gh-form-group errors=user.errors hasValidated=user.hasValidated property="location"}}
|
||||||
|
<label for="user-location">Location</label>
|
||||||
|
{{gh-input user.location type="text" id="user-location" focusOut=(action "validate" "location" target=user) update=(action (mut user.location))}}
|
||||||
|
{{gh-error-message errors=user.errors property="location"}}
|
||||||
|
<p>Where in the world do you live?</p>
|
||||||
|
{{/gh-form-group}}
|
||||||
|
|
||||||
|
{{#gh-form-group errors=user.errors hasValidated=user.hasValidated property="website"}}
|
||||||
|
<label for="user-website">Website</label>
|
||||||
|
{{gh-input user.website type="url" id="user-website" autocapitalize="off" autocorrect="off" autocomplete="off" focusOut=(action "validate" "website" target=user) update=(action (mut user.website))}}
|
||||||
|
{{gh-error-message errors=user.errors property="website"}}
|
||||||
|
<p>Have a website or blog other than this one? Link it!</p>
|
||||||
|
{{/gh-form-group}}
|
||||||
|
|
||||||
|
{{#gh-form-group errors=user.errors hasValidated=user.hasValidated property="facebook"}}
|
||||||
|
<label for="user-facebook">Facebook Profile</label>
|
||||||
|
<input value={{user.facebook}} oninput={{action (mut _scratchFacebook) value="target.value"}} {{action "validateFacebookUrl" on="focusOut"}} type="url" class="gh-input" id="user-facebook" name="user[facebook]" placeholder="https://www.facebook.com/username" autocorrect="off" />
|
||||||
|
{{gh-error-message errors=user.errors property="facebook"}}
|
||||||
|
<p>URL of your personal Facebook Profile</p>
|
||||||
|
{{/gh-form-group}}
|
||||||
|
|
||||||
|
{{#gh-form-group errors=user.errors hasValidated=user.hasValidated property="twitter"}}
|
||||||
|
<label for="user-twitter">Twitter Profile</label>
|
||||||
|
<input value={{user.twitter}} oninput={{action (mut _scratchTwitter) value="target.value"}} {{action "validateTwitterUrl" on="focusOut"}} type="url" class="gh-input" id="user-twitter" name="user[twitter]" placeholder="https://twitter.com/username" autocorrect="off" />
|
||||||
|
{{gh-error-message errors=user.errors property="twitter"}}
|
||||||
|
<p>URL of your personal Twitter profile</p>
|
||||||
|
{{/gh-form-group}}
|
||||||
|
|
||||||
|
{{#gh-form-group errors=user.errors hasValidated=user.hasValidated property="bio" class="bio-container"}}
|
||||||
|
<label for="user-bio">Bio</label>
|
||||||
|
{{gh-textarea user.bio id="user-bio" focusOut=(action "validate" "bio" target=user) update=(action (mut user.bio))}}
|
||||||
|
{{gh-error-message errors=user.errors property="bio"}}
|
||||||
|
<p>
|
||||||
|
Write about you, in 200 characters or less.
|
||||||
|
{{gh-count-characters user.bio}}
|
||||||
|
</p>
|
||||||
|
{{/gh-form-group}}
|
||||||
|
|
||||||
|
<hr />
|
||||||
|
|
||||||
</fieldset>
|
</fieldset>
|
||||||
</form> {{! change password form }}
|
|
||||||
{{/if}}
|
|
||||||
|
|
||||||
{{!-- when using Ghost OAuth, users trying to change email/pass need to visit my.ghost.org --}}
|
</form> {{! user details form }}
|
||||||
{{#if showMyGhostLink}}
|
|
||||||
<div class="user-profile">
|
{{!-- If an administrator is viewing Owner's profile or we're using Ghost.org OAuth then hide inputs for change password --}}
|
||||||
<p class="gh-box gh-box-info">{{inline-svg "lock"}} To change your login details please visit <a href="https://my.ghost.org/account" target="_blank">https://my.ghost.org/account</a></p>
|
{{#if canChangePassword}}
|
||||||
</div>
|
<form id="password-reset" class="user-profile" novalidate="novalidate" autocomplete="off" {{action (perform user.saveNewPassword) on="submit"}}>
|
||||||
{{/if}}
|
<fieldset>
|
||||||
|
{{#unless isNotOwnProfile}}
|
||||||
|
{{#gh-form-group errors=user.errors hasValidated=user.hasValidated property="password"}}
|
||||||
|
<label for="user-password-old">Old Password</label>
|
||||||
|
{{gh-input value=user.password type="password" id="user-password-old" update=(action 'updatePassword') onenter=(action (perform user.saveNewPassword))}}
|
||||||
|
{{gh-error-message errors=user.errors property="password"}}
|
||||||
|
{{/gh-form-group}}
|
||||||
|
{{/unless}}
|
||||||
|
|
||||||
|
{{#gh-form-group errors=user.errors hasValidated=user.hasValidated property="newPassword"}}
|
||||||
|
<label for="user-password-new">New Password</label>
|
||||||
|
{{gh-input user.newPassword type="password" id="user-password-new" update=(action 'updateNewPassword') onenter=(action (perform user.saveNewPassword))}}
|
||||||
|
{{gh-error-message errors=user.errors property="newPassword"}}
|
||||||
|
{{/gh-form-group}}
|
||||||
|
|
||||||
|
{{#gh-form-group errors=user.errors hasValidated=user.hasValidated property="ne2Password"}}
|
||||||
|
<label for="user-new-password-verification">Verify Password</label>
|
||||||
|
{{gh-input user.ne2Password type="password" id="user-new-password-verification" update=(action 'updateNe2Password') onenter=(action (perform user.saveNewPassword))}}
|
||||||
|
{{gh-error-message errors=user.errors property="ne2Password"}}
|
||||||
|
{{/gh-form-group}}
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
{{gh-task-button "Change Password" class="gh-btn gh-btn-red gh-btn-icon button-change-password" task=user.saveNewPassword}}
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
||||||
|
</form> {{! change password form }}
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
{{!-- when using Ghost OAuth, users trying to change email/pass need to visit my.ghost.org --}}
|
||||||
|
{{#if showMyGhostLink}}
|
||||||
|
<div class="user-profile">
|
||||||
|
<p class="gh-box gh-box-info">{{inline-svg "lock"}} To change your login details please visit <a href="https://my.ghost.org/account" target="_blank">https://my.ghost.org/account</a></p>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
@ -469,22 +469,22 @@ describe('Acceptance: Team', function () {
|
|||||||
await visit('/team/test-1');
|
await visit('/team/test-1');
|
||||||
|
|
||||||
expect(currentURL(), 'currentURL').to.equal('/team/test-1');
|
expect(currentURL(), 'currentURL').to.equal('/team/test-1');
|
||||||
expect(find('.user-details-top .first-form-group input.user-name').val(), 'current user name').to.equal('Test User');
|
expect(find('.user-details-bottom .first-form-group input.user-name').val(), 'current user name').to.equal('Test User');
|
||||||
|
|
||||||
// test empty user name
|
// test empty user name
|
||||||
await fillIn('.user-details-top .first-form-group input.user-name', '');
|
await fillIn('.user-details-bottom .first-form-group input.user-name', '');
|
||||||
await triggerEvent('.user-details-top .first-form-group input.user-name', 'blur');
|
await triggerEvent('.user-details-bottom .first-form-group input.user-name', 'blur');
|
||||||
|
|
||||||
expect(find('.user-details-top .first-form-group').hasClass('error'), 'username input is in error state with blank input').to.be.true;
|
expect(find('.user-details-bottom .first-form-group').hasClass('error'), 'username input is in error state with blank input').to.be.true;
|
||||||
|
|
||||||
// test too long user name
|
// test too long user name
|
||||||
await fillIn('.user-details-top .first-form-group input.user-name', new Array(160).join('a'));
|
await fillIn('.user-details-bottom .first-form-group input.user-name', new Array(160).join('a'));
|
||||||
await triggerEvent('.user-details-top .first-form-group input.user-name', 'blur');
|
await triggerEvent('.user-details-bottom .first-form-group input.user-name', 'blur');
|
||||||
|
|
||||||
expect(find('.user-details-top .first-form-group').hasClass('error'), 'username input is in error state with too long input').to.be.true;
|
expect(find('.user-details-bottom .first-form-group').hasClass('error'), 'username input is in error state with too long input').to.be.true;
|
||||||
|
|
||||||
// reset name field
|
// reset name field
|
||||||
await fillIn('.user-details-top .first-form-group input.user-name', 'Test User');
|
await fillIn('.user-details-bottom .first-form-group input.user-name', 'Test User');
|
||||||
|
|
||||||
expect(find('.user-details-bottom input[name="user"]').val(), 'slug value is default').to.equal('test-1');
|
expect(find('.user-details-bottom input[name="user"]').val(), 'slug value is default').to.equal('test-1');
|
||||||
|
|
||||||
@ -501,7 +501,7 @@ describe('Acceptance: Team', function () {
|
|||||||
await fillIn('.user-details-bottom input[name="email"]', 'thisisnotanemail');
|
await fillIn('.user-details-bottom input[name="email"]', 'thisisnotanemail');
|
||||||
await triggerEvent('.user-details-bottom input[name="email"]', 'blur');
|
await triggerEvent('.user-details-bottom input[name="email"]', 'blur');
|
||||||
|
|
||||||
expect(find('.user-details-bottom .form-group:nth-of-type(2)').hasClass('error'), 'email input should be in error state with invalid email').to.be.true;
|
expect(find('.user-details-bottom .form-group:nth-of-type(3)').hasClass('error'), 'email input should be in error state with invalid email').to.be.true;
|
||||||
|
|
||||||
await fillIn('.user-details-bottom input[name="email"]', 'test@example.com');
|
await fillIn('.user-details-bottom input[name="email"]', 'test@example.com');
|
||||||
await fillIn('#user-location', new Array(160).join('a'));
|
await fillIn('#user-location', new Array(160).join('a'));
|
||||||
|
@ -3,8 +3,8 @@ import {describe, it} from 'mocha';
|
|||||||
import {countCharacters} from 'ghost-admin/helpers/gh-count-characters';
|
import {countCharacters} from 'ghost-admin/helpers/gh-count-characters';
|
||||||
|
|
||||||
describe('Unit: Helper: gh-count-characters', function() {
|
describe('Unit: Helper: gh-count-characters', function() {
|
||||||
let defaultStyle = 'color: rgb(158, 157, 149);';
|
let defaultStyle = 'color: rgb(115, 138, 148);';
|
||||||
let errorStyle = 'color: rgb(226, 84, 64);';
|
let errorStyle = 'color: rgb(240, 82, 48);';
|
||||||
|
|
||||||
it('counts remaining chars', function() {
|
it('counts remaining chars', function() {
|
||||||
let result = countCharacters(['test']);
|
let result = countCharacters(['test']);
|
||||||
|
Loading…
Reference in New Issue
Block a user