mirror of
https://github.com/HabitRPG/habitica.git
synced 2025-12-16 14:17:22 +01:00
New client members (#8795)
* Began styling member modal * Added store and updated modal styles * Began converting angular * Ported over angular routes * Fixed lint issues
This commit is contained in:
3
website/client/assets/members/message.svg
Normal file
3
website/client/assets/members/message.svg
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="12" viewBox="0 0 16 12">
|
||||||
|
<path fill="#4F2A93" fill-rule="evenodd" d="M14 10H2V2l6 5 6-5v8zm0-10H2a2 2 0 0 0-2 2v8a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2z"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 235 B |
3
website/client/assets/members/remove.svg
Normal file
3
website/client/assets/members/remove.svg
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
||||||
|
<path fill="#878190" fill-rule="evenodd" d="M8 14a5.96 5.96 0 0 1-3.327-1.011l8.316-8.316A5.96 5.96 0 0 1 14 8c0 3.309-2.691 6-6 6M8 2a5.96 5.96 0 0 1 3.327 1.011l-8.316 8.316A5.96 5.96 0 0 1 2 8c0-3.309 2.691-6 6-6m0-2a8 8 0 1 0 0 16A8 8 0 0 0 8 0"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 347 B |
3
website/client/assets/members/star.svg
Normal file
3
website/client/assets/members/star.svg
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="17" height="16" viewBox="0 0 17 16">
|
||||||
|
<path fill="#878190" fill-rule="evenodd" d="M10.824 9.552l.604 3.553-3.16-1.677-3.157 1.677.604-3.553-2.58-2.537 3.563-.523 1.57-3.215 1.573 3.215 3.562.523-2.58 2.537zm4.859-4.225l-4.508-.66L9.168.56a1 1 0 0 0-1.797 0L5.364 4.666l-4.508.661A1 1 0 0 0 .3 7.03l3.268 3.216-.77 4.528a1 1 0 0 0 1.455 1.051l4.016-2.13 4.017 2.13a1 1 0 0 0 1.454-1.05l-.77-4.529L16.24 7.03a1 1 0 0 0-.556-1.702z"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 489 B |
@@ -47,9 +47,9 @@ export default {
|
|||||||
UserListDetail,
|
UserListDetail,
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapState({
|
...mapState({
|
||||||
user: 'user.data',
|
user: 'user.data',
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
.col-12
|
.col-12
|
||||||
h3(v-once) {{ $t('chat') }}
|
h3(v-once) {{ $t('chat') }}
|
||||||
|
|
||||||
textarea(placeholder="$('chatPlaceHolder')")
|
textarea(:placeholder="$t('chatPlaceHolder')")
|
||||||
button.btn.btn-secondary.send-chat.float-right(v-once) {{ $t('send') }}
|
button.btn.btn-secondary.send-chat.float-right(v-once) {{ $t('send') }}
|
||||||
|
|
||||||
.hr
|
.hr
|
||||||
@@ -66,9 +66,7 @@
|
|||||||
.col-6
|
.col-6
|
||||||
members-modal(:group='guild')
|
members-modal(:group='guild')
|
||||||
br
|
br
|
||||||
button.btn.btn-primary(v-once) {{$t('joinGuild')}}
|
button.btn.btn-primary(:class="[isMember ? 'btn-danger' : 'btn-success']") {{ isMember ? $t('leave') : $t('join') }}
|
||||||
br
|
|
||||||
button.btn.float-left(:class="[isMember ? 'btn-danger' : 'btn-success']") {{ isMember ? $t('leave') : $t('join') }}
|
|
||||||
br
|
br
|
||||||
button.btn.btn-primary(v-once) {{$t('inviteToGuild')}}
|
button.btn.btn-primary(v-once) {{$t('inviteToGuild')}}
|
||||||
br
|
br
|
||||||
@@ -289,18 +287,6 @@ export default {
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
},
|
},
|
||||||
editGroup () {
|
|
||||||
// @TODO: Open up model
|
|
||||||
},
|
|
||||||
save () {
|
|
||||||
let newLeader = this.group._newLeader && this.group._newLeader._id;
|
|
||||||
|
|
||||||
if (newLeader) {
|
|
||||||
this.group.leader = newLeader;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Groups.Group.update(group);
|
|
||||||
},
|
|
||||||
deleteAllMessages () {
|
deleteAllMessages () {
|
||||||
if (confirm(this.$t('confirmDeleteAllMessages'))) {
|
if (confirm(this.$t('confirmDeleteAllMessages'))) {
|
||||||
// User.clearPMs();
|
// User.clearPMs();
|
||||||
|
|||||||
@@ -2,30 +2,41 @@
|
|||||||
div
|
div
|
||||||
button.btn.btn-primary(b-btn, @click="$root.$emit('show::modal','members-modal')") {{ $t('viewMembers') }}
|
button.btn.btn-primary(b-btn, @click="$root.$emit('show::modal','members-modal')") {{ $t('viewMembers') }}
|
||||||
|
|
||||||
b-modal#members-modal(:title="$t('createGuild')")
|
b-modal#members-modal(:title="$t('createGuild')", size='lg')
|
||||||
.header-wrap(slot="modal-header")
|
.header-wrap(slot="modal-header")
|
||||||
.row
|
.row
|
||||||
.col-6
|
.col-6
|
||||||
h1 Testing
|
h1(v-once) {{$t('members')}}
|
||||||
.col-6
|
.col-6
|
||||||
button(type="button" aria-label="Close" class="close")
|
button(type="button" aria-label="Close" class="close")
|
||||||
span(aria-hidden="true") ×
|
span(aria-hidden="true") ×
|
||||||
.row
|
.row
|
||||||
.form-group.col-6
|
.form-group.col-6
|
||||||
input.form-control.search(type="text", :placeholder="$t('search')", v-model='searchTerm')
|
input.form-control.search(type="text", :placeholder="$t('search')", v-model='searchTerm')
|
||||||
.col-6
|
.col-4.offset-2
|
||||||
span.dropdown-label {{ $t('sortBy') }}
|
span.dropdown-label {{ $t('sortBy') }}
|
||||||
b-dropdown(:text="$t('sort')", right=true)
|
b-dropdown(:text="$t('sort')", right=true)
|
||||||
b-dropdown-item(v-for='sortOption in sortOptions', :key="sortOption.value", @click='sort(sortOption.value)') {{sortOption.text}}
|
b-dropdown-item(v-for='sortOption in sortOptions', @click='sort(sortOption.value)', :key='sortOption.value') {{sortOption.text}}
|
||||||
.row(v-for='member in members', :key='member', )
|
.row(v-for='member in members', :key='member', )
|
||||||
.col-8
|
.col-8.offset-1
|
||||||
user-list-detail
|
user-list-detail(:user='member')
|
||||||
.col-4
|
.col-3.actions
|
||||||
b-dropdown(:text="$t('sort')", right=true)
|
b-dropdown(:text="$t('sort')", right=true)
|
||||||
b-dropdown-item(@click='sort(option.value)') {{$t('remove')}}
|
b-dropdown-item(@click='sort(option.value)')
|
||||||
b-dropdown-item(@click='sort(option.value)') {{$t('message')}}
|
img.action-icon(src='~assets/members/remove.svg')
|
||||||
b-dropdown-item(@click='sort(option.value)') {{$t('addManager')}}
|
| {{$t('removeMember')}}
|
||||||
b-dropdown-item(@click='sort(option.value)') {{$t('removeManager')}}
|
b-dropdown-item(@click='sort(option.value)')
|
||||||
|
img.action-icon(src='~assets/members/message.svg')
|
||||||
|
| {{$t('sendMessage')}}
|
||||||
|
b-dropdown-item(@click='sort(option.value)')
|
||||||
|
img.action-icon(src='~assets/members/star.svg')
|
||||||
|
| {{$t('promoteToLeader')}}
|
||||||
|
b-dropdown-item(@click='sort(option.value)')
|
||||||
|
img.action-icon(src='~assets/members/star.svg')
|
||||||
|
| {{$t('addManager')}}
|
||||||
|
b-dropdown-item(@click='sort(option.value)')
|
||||||
|
img.action-icon(src='~assets/members/remove.svg')
|
||||||
|
| {{$t('removeManager2')}}
|
||||||
|
|
||||||
b-modal#remove-member(:title="$t('confirmRemoveMember')")
|
b-modal#remove-member(:title="$t('confirmRemoveMember')")
|
||||||
button(@click='confirmRemoveMember(member)', v-once) {{$t('remove')}}
|
button(@click='confirmRemoveMember(member)', v-once) {{$t('remove')}}
|
||||||
@@ -35,20 +46,26 @@ div
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style lang='scss'>
|
<style lang='scss'>
|
||||||
|
header {
|
||||||
|
background-color: #edecee;
|
||||||
|
border-radius: 4px 4px 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
header {
|
.header-wrap {
|
||||||
background-color: #edecee;
|
width: 100%;
|
||||||
border-radius: 4px 4px 0 0;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
.header-wrap {
|
h1 {
|
||||||
width: 100%;
|
color: #4f2a93;
|
||||||
}
|
}
|
||||||
|
|
||||||
h1 {
|
.actions {
|
||||||
color: #4f2a93;
|
padding-top: 5em;
|
||||||
}
|
|
||||||
|
|
||||||
|
.action-icon {
|
||||||
|
margin-right: 1em;
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
@@ -66,17 +83,43 @@ export default {
|
|||||||
bDropdownItem,
|
bDropdownItem,
|
||||||
UserListDetail,
|
UserListDetail,
|
||||||
},
|
},
|
||||||
|
created () {
|
||||||
|
this.getMembers();
|
||||||
|
},
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
members: ['one', 'two'],
|
members: [],
|
||||||
memberToRemove: '',
|
memberToRemove: '',
|
||||||
|
sortOptions: [
|
||||||
|
{
|
||||||
|
value: 'tier',
|
||||||
|
text: this.$t('tier'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'name',
|
||||||
|
text: this.$t('name'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'level',
|
||||||
|
text: this.$t('level'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'class',
|
||||||
|
text: this.$t('class'),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
searchTerm: '',
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
getMembers () {
|
async getMembers () {
|
||||||
// We should get members here via store if they are not loaded
|
let members = await this.$store.dispatch('members:getGroupMembers', {
|
||||||
|
groupId: this.group._id,
|
||||||
|
includeAllPublicFields: true,
|
||||||
|
});
|
||||||
|
this.members = members;
|
||||||
},
|
},
|
||||||
clickMember (uid, forceShow) {
|
async clickMember (uid, forceShow) {
|
||||||
let user = this.$store.state.user.data;
|
let user = this.$store.state.user.data;
|
||||||
|
|
||||||
if (user._id === uid && !forceShow) {
|
if (user._id === uid && !forceShow) {
|
||||||
@@ -89,59 +132,47 @@ export default {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// $root.$emit('show::modal','members-modal')
|
await this.$store.dispatch('members:selectMember', {
|
||||||
// We need the member information up top here, but then we pass it down to the modal controller
|
memberId: uid,
|
||||||
// down below. Better way of handling this?
|
});
|
||||||
// Members.selectMember(uid)
|
|
||||||
// .then(function () {
|
this.$root.$emit('show::modal', 'members-modal');
|
||||||
// $rootScope.openModal('member', {controller: 'MemberModalCtrl', windowClass: 'profile-modal', size: 'lg'});
|
|
||||||
// });
|
|
||||||
},
|
},
|
||||||
removeMember (member) {
|
async removeMember (member) {
|
||||||
this.memberToRemove = member;
|
this.memberToRemove = member;
|
||||||
this.$root.$emit('show::modal', 'remove-member');
|
this.$root.$emit('show::modal', 'remove-member');
|
||||||
},
|
},
|
||||||
confirmRemoveMember (confirmation) {
|
async confirmRemoveMember (confirmation) {
|
||||||
if (!confirmation) {
|
if (!confirmation) {
|
||||||
this.memberToRemove = '';
|
this.memberToRemove = '';
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Groups.Group.removeMember(
|
|
||||||
// $scope.removeMemberData.group._id,
|
await this.$store.dispatch('members:removeMember', {
|
||||||
// $scope.removeMemberData.member._id,
|
memberId: this.memberToRemove._id,
|
||||||
// $scope.removeMemberData.message
|
groupId: this.group._id,
|
||||||
// ).then(function (response) {
|
message: this.removeMessage,
|
||||||
// if($scope.removeMemberData.isMember){
|
});
|
||||||
// _.pull($scope.removeMemberData.group.members, $scope.removeMemberData.member);
|
|
||||||
// }else{
|
this.memberToRemove = '';
|
||||||
// _.pull($scope.removeMemberData.group.invites, $scope.removeMemberData.member);
|
this.removeMessage = '';
|
||||||
// }
|
|
||||||
//
|
|
||||||
// $scope.removeMemberData = undefined;
|
|
||||||
// });
|
|
||||||
},
|
},
|
||||||
quickReply (uid) {
|
async quickReply (uid) {
|
||||||
this.memberToReply = uid;
|
this.memberToReply = uid;
|
||||||
this.$root.$emit('show::modal', 'private-message');
|
await this.$store.dispatch('members:selectMember', {
|
||||||
// Members.selectMember(uid)
|
memberId: uid,
|
||||||
// .then(function (response) {
|
});
|
||||||
// $rootScope.openModal('private-message', {controller: 'MemberModalCtrl'});
|
this.$root.$emit('show::modal', 'private-message'); // MemberModalCtrl
|
||||||
// });
|
|
||||||
},
|
},
|
||||||
addManager () {
|
async addManager (memberId) {
|
||||||
// Groups.Group.addManager(this.group._id, this.group._newManager)
|
await this.$store.dispatch('group:addManager', {
|
||||||
// .then(function (response) {
|
memberId,
|
||||||
// this.group._newManager = '';
|
});
|
||||||
// this.group.managers = response.data.data.managers;
|
|
||||||
// });
|
|
||||||
},
|
},
|
||||||
removeManager (memberId) {
|
async removeManager (memberId) {
|
||||||
this.memberToReply = memberId;
|
await this.$store.dispatch('group:removeManager', {
|
||||||
// Groups.Group.removeManager(this.group._id, memberId)
|
memberId,
|
||||||
// .then(function (response) {
|
});
|
||||||
// this.group._newManager = '';
|
|
||||||
// this.group.managers = response.data.data.managers;
|
|
||||||
// });
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
.d-flex
|
.d-flex
|
||||||
avatar#header-avatar(:user="user")
|
avatar#header-avatar(:user="user")
|
||||||
div
|
div
|
||||||
h3.character-name
|
h3.character-name
|
||||||
| {{user.profile.name}}
|
| {{user.profile.name}}
|
||||||
.is-buffed(v-if="isBuffed")
|
.is-buffed(v-if="isBuffed")
|
||||||
.svg-icon(v-html="icons.buff")
|
.svg-icon(v-html="icons.buff")
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import * as common from './common';
|
|||||||
import * as user from './user';
|
import * as user from './user';
|
||||||
import * as tasks from './tasks';
|
import * as tasks from './tasks';
|
||||||
import * as guilds from './guilds';
|
import * as guilds from './guilds';
|
||||||
|
import * as members from './members';
|
||||||
|
|
||||||
// Actions should be named as 'actionName' and can be accessed as 'namespace:actionName'
|
// Actions should be named as 'actionName' and can be accessed as 'namespace:actionName'
|
||||||
// Example: fetch in user.js -> 'user:fetch'
|
// Example: fetch in user.js -> 'user:fetch'
|
||||||
@@ -13,6 +14,7 @@ const actions = flattenAndNamespace({
|
|||||||
user,
|
user,
|
||||||
tasks,
|
tasks,
|
||||||
guilds,
|
guilds,
|
||||||
|
members,
|
||||||
});
|
});
|
||||||
|
|
||||||
export default actions;
|
export default actions;
|
||||||
|
|||||||
104
website/client/store/actions/members.js
Normal file
104
website/client/store/actions/members.js
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
import axios from 'axios';
|
||||||
|
// import omit from 'lodash/omit';
|
||||||
|
// import findIndex from 'lodash/findIndex';
|
||||||
|
|
||||||
|
let apiV3Prefix = '/api/v3';
|
||||||
|
|
||||||
|
export async function getGroupMembers (store, payload) {
|
||||||
|
let url = `${apiV3Prefix}/groups/${payload.groupId}/members`;
|
||||||
|
if (payload.includeAllPublicFields) {
|
||||||
|
url += '?includeAllPublicFields=true';
|
||||||
|
}
|
||||||
|
let response = await axios.get(url);
|
||||||
|
return response.data.data;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function fetchMember (store, payload) {
|
||||||
|
let url = `${apiV3Prefix}/members/${payload.memberId}`;
|
||||||
|
let response = await axios.get(url);
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function getGroupInvites (store, payload) {
|
||||||
|
let url = `${apiV3Prefix}/groups/${payload.groupId}/invites`;
|
||||||
|
let response = await axios.get(url);
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function getChallengeMembers (store, payload) {
|
||||||
|
let url = `${apiV3Prefix}/challenges/${payload.challengeId}/members?includeAllMembers=true`;
|
||||||
|
let response = await axios.get(url);
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function getChallengeMemberProgress (store, payload) {
|
||||||
|
let url = `${apiV3Prefix}/challenges/${payload.challengeId}/members/${payload.memberId}`;
|
||||||
|
let response = await axios.get(url);
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function sendPrivateMessage (store, payload) {
|
||||||
|
let url = `${apiV3Prefix}/members/send-private-message`;
|
||||||
|
let data = {
|
||||||
|
message: payload.message,
|
||||||
|
toUserId: payload.toUserId,
|
||||||
|
};
|
||||||
|
let response = await axios.post(url, data);
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function transferGems (store, payload) {
|
||||||
|
let url = `${apiV3Prefix}/members/transfer-gems`;
|
||||||
|
let data = {
|
||||||
|
message: payload.message,
|
||||||
|
toUserId: payload.toUserId,
|
||||||
|
gemAmount: payload.gemAmount,
|
||||||
|
};
|
||||||
|
let response = await axios.post(url, data);
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function removeMember (store, payload) {
|
||||||
|
let url = `${apiV3Prefix}/groups/${payload.groupId}/removeMember/${payload.memberId}`;
|
||||||
|
let data = {
|
||||||
|
message: payload.message,
|
||||||
|
};
|
||||||
|
let response = await axios.post(url, data);
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
// export async function selectMember (uid) {
|
||||||
|
// let memberIsReady = _checkIfMemberIsReady(members[uid]);
|
||||||
|
//
|
||||||
|
// if (memberIsReady) {
|
||||||
|
// _prepareMember(members[uid], self);
|
||||||
|
// return
|
||||||
|
// } else {
|
||||||
|
// fetchMember(uid)
|
||||||
|
// .then(function (response) {
|
||||||
|
// var member = response.data.data;
|
||||||
|
// addToMembersList(member); // lazy load for later
|
||||||
|
// _prepareMember(member, self);
|
||||||
|
// deferred.resolve();
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// function addToMembersList (member) {
|
||||||
|
// if (member._id) {
|
||||||
|
// members[member._id] = member;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// function _checkIfMemberIsReady (member) {
|
||||||
|
// return member && member.items && member.items.weapon;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// function _prepareMember(member, self) {
|
||||||
|
// Shared.wrap(member, false);
|
||||||
|
// self.selectedMember = members[member._id];
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// $rootScope.$on('userUpdated', function(event, user){
|
||||||
|
// addToMembersList(user);
|
||||||
|
// })
|
||||||
@@ -64,5 +64,9 @@
|
|||||||
"noGuildsParagraph1": "Guilds are social groups created by other players that can offer you support, accountability, and encouraging chat.",
|
"noGuildsParagraph1": "Guilds are social groups created by other players that can offer you support, accountability, and encouraging chat.",
|
||||||
"noGuildsParagraph2": "Click the Discover tab to see recommended Guilds based on your interests, browse Habitica’s public Guilds, or create your own Guild.",
|
"noGuildsParagraph2": "Click the Discover tab to see recommended Guilds based on your interests, browse Habitica’s public Guilds, or create your own Guild.",
|
||||||
"privateDescription": "A private Guild will not be displayed in Habitica’s Guild directory. New members can be added by invitation only.",
|
"privateDescription": "A private Guild will not be displayed in Habitica’s Guild directory. New members can be added by invitation only.",
|
||||||
|
"removeMember": "Remove Member",
|
||||||
|
"sendMessage": "Send Message",
|
||||||
|
"removeManager2": "Remove Manager",
|
||||||
|
"promoteToLeader": "Promote to Leader",
|
||||||
"inviteFriendsParty": "Inviting friends to your party will grant you an exclusive <br/> Quest Scroll to battle the Basi-List together!"
|
"inviteFriendsParty": "Inviting friends to your party will grant you an exclusive <br/> Quest Scroll to battle the Basi-List together!"
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user