mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-21 20:47:08 -05:00
Improve UX of user profile
This commit is contained in:
parent
452098ca68
commit
41ef675999
3 changed files with 164 additions and 118 deletions
|
@ -26,17 +26,17 @@ block content
|
||||||
ul.dropdown-menu(role="menu")
|
ul.dropdown-menu(role="menu")
|
||||||
li
|
li
|
||||||
a(
|
a(
|
||||||
href="#",
|
href,
|
||||||
ng-click="openCreateProjectModal()"
|
ng-click="openCreateProjectModal()"
|
||||||
) Blank Project
|
) Blank Project
|
||||||
li
|
li
|
||||||
a(
|
a(
|
||||||
href="#",
|
href,
|
||||||
ng-click="openCreateProjectModal('example')"
|
ng-click="openCreateProjectModal('example')"
|
||||||
) Example Project
|
) Example Project
|
||||||
li
|
li
|
||||||
a(
|
a(
|
||||||
href="#",
|
href,
|
||||||
ng-click="openUploadProjectModal()"
|
ng-click="openUploadProjectModal()"
|
||||||
) Upload Project
|
) Upload Project
|
||||||
li.divider
|
li.divider
|
||||||
|
@ -55,7 +55,8 @@ block content
|
||||||
a.menu-indent(href="/templates/bibliographies") Bibliographies
|
a.menu-indent(href="/templates/bibliographies") Bibliographies
|
||||||
li
|
li
|
||||||
a.menu-indent(href="/templates") View All »
|
a.menu-indent(href="/templates") View All »
|
||||||
.row-spaced
|
|
||||||
|
.row-spaced(ng-if="projects.length > 0", ng-cloak)
|
||||||
ul.list-unstyled.folders-menu(
|
ul.list-unstyled.folders-menu(
|
||||||
ng-controller="TagListController"
|
ng-controller="TagListController"
|
||||||
)
|
)
|
||||||
|
@ -85,68 +86,33 @@ block content
|
||||||
| {{tag.name}}
|
| {{tag.name}}
|
||||||
span.subdued ({{tag.project_ids.length}})
|
span.subdued ({{tag.project_ids.length}})
|
||||||
|
|
||||||
|
.row-spaced(ng-if="projects.length == 0", ng-cloak)
|
||||||
|
.first-project
|
||||||
|
div
|
||||||
|
i.fa.fa-arrow-up.fa-2x
|
||||||
|
div
|
||||||
|
strong Create your first project!
|
||||||
|
|
||||||
-if (settings.enableSubscriptions)
|
-if (settings.enableSubscriptions)
|
||||||
.row-spaced
|
.row-spaced(ng-if="projects.length > 0", ng-cloak)
|
||||||
a(href="/user/bonus").btn.btn-info Upgrade Account
|
a(href="/user/bonus").btn.btn-info Upgrade Account
|
||||||
|
|
||||||
- if (showUserDetailsArea)
|
- if (showUserDetailsArea)
|
||||||
.row-spaced#userProfileInformation(ng-cloak)
|
.row-spaced#userProfileInformation(ng-if="projects.length > 0 && percentComplete < 100", ng-cloak)
|
||||||
div(ng-controller="UpdateForm").userProfileInformationArea
|
div(ng-controller="UserProfileController")
|
||||||
div(ng-hide="hidePersonalInfoSection").alert.alert-info
|
.alert.alert-info.text-centered.user-profile
|
||||||
div(ng-show="percentComplete >= 100")
|
|
||||||
h4 100% complete, well done!
|
|
||||||
div(ng-hide="percentComplete >= 100")
|
|
||||||
h4 Your profile is
|
|
||||||
strong {{percentComplete}}%
|
|
||||||
| complete
|
|
||||||
|
|
||||||
.progress
|
.progress
|
||||||
.progress-bar.progress-bar-info(ng-style="{'width' : (percentComplete+'%')}")
|
.progress-bar.progress-bar-info(ng-style="{'width' : (percentComplete+'%')}")
|
||||||
|
|
||||||
button#completeUserProfileInformation.btn.btn-primary(
|
p.small
|
||||||
ng-hide="formVisable",
|
| Your profile is
|
||||||
ng-click="showForm()"
|
strong {{percentComplete}}%
|
||||||
) Complete now
|
| complete
|
||||||
|
|
||||||
div(ng-show="formVisable")
|
button#completeUserProfileInformation.btn.btn-primary.btn-sm(
|
||||||
form(enctype='multipart/form-data', method='post')
|
ng-hide="formVisable",
|
||||||
.form-group
|
ng-click="openUserProfileModal()"
|
||||||
input.form-control(
|
) Complete
|
||||||
type='text',
|
|
||||||
name='first_name',
|
|
||||||
ng-model="userInfoForm.first_name",
|
|
||||||
ng-blur="sendUpdate()",
|
|
||||||
placeholder="First Name",
|
|
||||||
select-when="formVisable"
|
|
||||||
)
|
|
||||||
.form-group
|
|
||||||
input.form-control(
|
|
||||||
type='text',
|
|
||||||
name='last_name',
|
|
||||||
ng-model="userInfoForm.last_name",
|
|
||||||
ng-blur="sendUpdate()",
|
|
||||||
placeholder='Last Name'
|
|
||||||
)
|
|
||||||
.form-group#institution_auto_complete
|
|
||||||
autocomplete(
|
|
||||||
ng-model="userInfoForm.institution",
|
|
||||||
data="institutions",
|
|
||||||
ng-blur="sendUpdate()",
|
|
||||||
on-type="updateInstitutionsList",
|
|
||||||
attr-placeholder="Institution",
|
|
||||||
attr-inputclass="form-control"
|
|
||||||
)
|
|
||||||
.form-group
|
|
||||||
input.form-control(
|
|
||||||
type='text',
|
|
||||||
name='role',
|
|
||||||
ng-model="userInfoForm.role",
|
|
||||||
placeholder='Role',
|
|
||||||
ng-blur="sendUpdate()",
|
|
||||||
list="_roles"
|
|
||||||
)
|
|
||||||
datalist#_roles
|
|
||||||
option(ng-repeat='role in roles') {{role}}
|
|
||||||
|
|
||||||
.col-md-10
|
.col-md-10
|
||||||
.container-fluid
|
.container-fluid
|
||||||
|
@ -258,52 +224,59 @@ block content
|
||||||
.row.row-spaced
|
.row.row-spaced
|
||||||
.col-md-12
|
.col-md-12
|
||||||
.card.card-thin
|
.card.card-thin
|
||||||
- if (projects.length > 0)
|
ul.list-unstyled.project-list(
|
||||||
ul.list-unstyled.project-list(select-all-list, ng-cloak)
|
select-all-list,
|
||||||
li.container-fluid
|
ng-if="projects.length > 0",
|
||||||
.row
|
ng-cloak
|
||||||
.col-md-6
|
)
|
||||||
input.select-all(
|
li.container-fluid
|
||||||
select-all,
|
.row
|
||||||
type="checkbox"
|
.col-md-6
|
||||||
)
|
input.select-all(
|
||||||
span.title TITLE
|
select-all,
|
||||||
.col-md-2
|
type="checkbox"
|
||||||
span.owner OWNER
|
)
|
||||||
.col-md-4
|
span.title TITLE
|
||||||
span.last-modified LAST MODIFIED
|
.col-md-2
|
||||||
li.project_entry.container-fluid(
|
span.owner OWNER
|
||||||
ng-repeat="project in visibleProjects | orderBy:'lastUpdated':true",
|
.col-md-4
|
||||||
ng-controller="ProjectListItemController"
|
span.last-modified LAST MODIFIED
|
||||||
)
|
li.project_entry.container-fluid(
|
||||||
.row
|
ng-repeat="project in visibleProjects | orderBy:'lastUpdated':true",
|
||||||
.col-md-6
|
ng-controller="ProjectListItemController"
|
||||||
input.select-item(
|
)
|
||||||
select-individual,
|
.row
|
||||||
type="checkbox",
|
.col-md-6
|
||||||
ng-model="project.selected"
|
input.select-item(
|
||||||
)
|
select-individual,
|
||||||
span.title
|
type="checkbox",
|
||||||
a.projectName(href="/project/{{project.id}}") {{project.name}}
|
ng-model="project.selected"
|
||||||
span
|
)
|
||||||
span.label.label-default(ng-repeat='tag in project.tags')
|
span.title
|
||||||
| {{tag.name}}
|
a.projectName(href="/project/{{project.id}}") {{project.name}}
|
||||||
.col-md-2
|
span
|
||||||
span.owner {{ownerName()}}
|
span.label.label-default(ng-repeat='tag in project.tags')
|
||||||
.col-md-4
|
| {{tag.name}}
|
||||||
span.last-modified.isoDate {{project.lastUpdated | formatDate}}
|
.col-md-2
|
||||||
- else
|
span.owner {{ownerName()}}
|
||||||
.row
|
.col-md-4
|
||||||
.span12
|
span.last-modified.isoDate {{project.lastUpdated | formatDate}}
|
||||||
.welcome
|
li(
|
||||||
h1
|
ng-if="visibleProjects.length == 0",
|
||||||
i.fa.fa-arrow-left
|
ng-cloak
|
||||||
| Welcome! Follow the arrow to get started
|
)
|
||||||
p New to LaTeX? Start by having a look at our
|
.row
|
||||||
a(href="/templates") templates
|
.col-md-12.text-centered
|
||||||
| or
|
small No projects
|
||||||
a(href="/learn") help guides
|
div.welcome.text-centered(ng-if="projects.length == 0", ng-cloak)
|
||||||
| .
|
h2 Welcome to ShareLaTeX!
|
||||||
|
p New to LaTeX? Start by having a look at our
|
||||||
|
a(href="/templates") templates
|
||||||
|
| or
|
||||||
|
a(href="/learn") help guides
|
||||||
|
| ,
|
||||||
|
br
|
||||||
|
| or create your first project on the left.
|
||||||
|
|
||||||
script(type='text/ng-template', id='newTagModalTemplate')
|
script(type='text/ng-template', id='newTagModalTemplate')
|
||||||
.modal-header
|
.modal-header
|
||||||
|
@ -436,3 +409,53 @@ block content
|
||||||
span Upload a zipped project
|
span Upload a zipped project
|
||||||
.modal-footer
|
.modal-footer
|
||||||
button.btn.btn-default(ng-click="cancel()") Cancel
|
button.btn.btn-default(ng-click="cancel()") Cancel
|
||||||
|
|
||||||
|
script(type="text/ng-template", id="userProfileModalTemplate")
|
||||||
|
.modal-header
|
||||||
|
h3 Your Profile
|
||||||
|
.modal-body
|
||||||
|
form(enctype='multipart/form-data', method='post')
|
||||||
|
.form-group
|
||||||
|
label(for="first_name") First Name
|
||||||
|
input.form-control(
|
||||||
|
type='text',
|
||||||
|
name='first_name',
|
||||||
|
ng-model="userInfoForm.first_name",
|
||||||
|
ng-blur="sendUpdate()",
|
||||||
|
placeholder="First Name",
|
||||||
|
select-when="formVisable"
|
||||||
|
)
|
||||||
|
.form-group
|
||||||
|
label(for="last_name") Last Name
|
||||||
|
input.form-control(
|
||||||
|
type='text',
|
||||||
|
name='last_name',
|
||||||
|
ng-model="userInfoForm.last_name",
|
||||||
|
ng-blur="sendUpdate()",
|
||||||
|
placeholder='Last Name'
|
||||||
|
)
|
||||||
|
.form-group#institution_auto_complete
|
||||||
|
label(for="institution") Institution
|
||||||
|
autocomplete(
|
||||||
|
ng-model="userInfoForm.institution",
|
||||||
|
name="institution",
|
||||||
|
data="institutions",
|
||||||
|
ng-blur="sendUpdate()",
|
||||||
|
on-type="updateInstitutionsList",
|
||||||
|
attr-placeholder="Institution",
|
||||||
|
attr-inputclass="form-control"
|
||||||
|
)
|
||||||
|
.form-group
|
||||||
|
label(for="role") Role
|
||||||
|
input.form-control(
|
||||||
|
type='text',
|
||||||
|
name='role',
|
||||||
|
ng-model="userInfoForm.role",
|
||||||
|
placeholder='Role',
|
||||||
|
ng-blur="sendUpdate()",
|
||||||
|
list="_roles"
|
||||||
|
)
|
||||||
|
datalist#_roles
|
||||||
|
option(ng-repeat='role in roles') {{role}}
|
||||||
|
.modal-footer
|
||||||
|
button.btn.btn-info(ng-click="done()") Done
|
||||||
|
|
|
@ -5,12 +5,8 @@ define [
|
||||||
app.factory "Institutions", ->
|
app.factory "Institutions", ->
|
||||||
new AlgoliaSearch(window.algolia.institutions.app_id, window.algolia.institutions.api_key).initIndex("institutions")
|
new AlgoliaSearch(window.algolia.institutions.app_id, window.algolia.institutions.api_key).initIndex("institutions")
|
||||||
|
|
||||||
App.controller "UpdateForm", ($scope, $http, Institutions)->
|
App.controller "UserProfileController", ($scope, $modal, $http)->
|
||||||
$scope.institutions = []
|
$scope.institutions = []
|
||||||
$scope.formVisable = false
|
|
||||||
$scope.hidePersonalInfoSection = true
|
|
||||||
$scope.roles = ["Student", "Post-graduate student", "Post-doctoral researcher", "Lecturer", "Professor"]
|
|
||||||
|
|
||||||
$http.get("/user/personal_info").success (data)->
|
$http.get("/user/personal_info").success (data)->
|
||||||
$scope.userInfoForm =
|
$scope.userInfoForm =
|
||||||
first_name: data.first_name || ""
|
first_name: data.first_name || ""
|
||||||
|
@ -19,23 +15,33 @@ define [
|
||||||
institution: data.institution || ""
|
institution: data.institution || ""
|
||||||
_csrf : window.csrfToken
|
_csrf : window.csrfToken
|
||||||
|
|
||||||
if getPercentComplete() != 100
|
|
||||||
$scope.percentComplete = getPercentComplete()
|
|
||||||
$scope.hidePersonalInfoSection = false
|
|
||||||
|
|
||||||
$scope.showForm = ->
|
$scope.showForm = ->
|
||||||
$scope.formVisable = true
|
$scope.formVisable = true
|
||||||
|
|
||||||
|
$scope.getPercentComplete = ->
|
||||||
|
results = _.filter $scope.userInfoForm, (value)-> !value? or value?.length != 0
|
||||||
|
results.length * 20
|
||||||
|
|
||||||
|
$scope.$watch "userInfoForm", (value) ->
|
||||||
|
if value?
|
||||||
|
$scope.percentComplete = $scope.getPercentComplete()
|
||||||
|
, true
|
||||||
|
|
||||||
|
$scope.openUserProfileModal = () ->
|
||||||
|
$modal.open {
|
||||||
|
templateUrl: "userProfileModalTemplate"
|
||||||
|
controller: "UserProfileModalController"
|
||||||
|
scope: $scope
|
||||||
|
}
|
||||||
|
|
||||||
|
App.controller "UserProfileModalController", ($scope, $modalInstance, $http, Institutions) ->
|
||||||
|
$scope.roles = ["Student", "Post-graduate student", "Post-doctoral researcher", "Lecturer", "Professor"]
|
||||||
|
|
||||||
$scope.sendUpdate = ->
|
$scope.sendUpdate = ->
|
||||||
request = $http.post "/user/settings", $scope.userInfoForm
|
request = $http.post "/user/settings", $scope.userInfoForm
|
||||||
request.success (data, status)->
|
request.success (data, status)->
|
||||||
request.error (data, status)->
|
request.error (data, status)->
|
||||||
console.log "the request failed"
|
console.log "the request failed"
|
||||||
$scope.percentComplete = getPercentComplete()
|
|
||||||
|
|
||||||
getPercentComplete = ->
|
|
||||||
results = _.filter $scope.userInfoForm, (value)-> !value? or value?.length != 0
|
|
||||||
results.length * 20
|
|
||||||
|
|
||||||
$scope.updateInstitutionsList = (inputVal)->
|
$scope.updateInstitutionsList = (inputVal)->
|
||||||
|
|
||||||
|
@ -48,3 +54,5 @@ define [
|
||||||
$scope.institutions = _.map response.hits, (institution)->
|
$scope.institutions = _.map response.hits, (institution)->
|
||||||
"#{institution.name} (#{institution.domain})"
|
"#{institution.name} (#{institution.domain})"
|
||||||
|
|
||||||
|
$scope.done = () ->
|
||||||
|
$modalInstance.close()
|
||||||
|
|
|
@ -13,6 +13,21 @@
|
||||||
display: inline;
|
display: inline;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.first-project {
|
||||||
|
width: 127px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-profile {
|
||||||
|
.progress {
|
||||||
|
height: @line-height-computed / 2;
|
||||||
|
margin-bottom: @line-height-computed / 4;
|
||||||
|
}
|
||||||
|
p {
|
||||||
|
margin-bottom: @line-height-computed / 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ul.folders-menu {
|
ul.folders-menu {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
.subdued {
|
.subdued {
|
||||||
|
|
Loading…
Reference in a new issue