Skip to content
This repository was archived by the owner on Apr 19, 2023. It is now read-only.

Commit 25eda95

Browse files
✨ Org members
1 parent 4270ce6 commit 25eda95

File tree

6 files changed

+191
-10
lines changed

6 files changed

+191
-10
lines changed

components/Manage.vue

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,13 @@
33
<aside>
44
<nav>
55
<nuxt-link class="item" to="/manage/settings">
6-
<font-awesome-icon class="nav-icon" icon="users" fixed-width />
6+
<font-awesome-icon class="nav-icon" icon="cog" fixed-width />
77
<span>Settings</span>
88
</nuxt-link>
9+
<nuxt-link class="item" to="/manage/members">
10+
<font-awesome-icon class="nav-icon" icon="users" fixed-width />
11+
<span>Members</span>
12+
</nuxt-link>
913
<!-- <nuxt-link class="item" to="/manage/data">
1014
<font-awesome-icon class="nav-icon" icon="database" fixed-width />
1115
<span>Data &amp; security</span>
@@ -23,8 +27,8 @@ import { Component, Vue } from "vue-property-decorator";
2327
import { mapGetters } from "vuex";
2428
import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome";
2529
import { library } from "@fortawesome/fontawesome-svg-core";
26-
import { faDatabase, faUsers } from "@fortawesome/free-solid-svg-icons";
27-
library.add(faDatabase, faUsers);
30+
import { faDatabase, faUsers, faCog } from "@fortawesome/free-solid-svg-icons";
31+
library.add(faDatabase, faUsers, faCog);
2832
2933
@Component({
3034
components: {

layouts/default.vue

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -139,9 +139,6 @@ a {
139139
&:hover {
140140
text-decoration: none;
141141
}
142-
+ .button {
143-
margin-left: 0.5rem;
144-
}
145142
}
146143
.button--size-large {
147144
font-size: 120%;

pages/manage/members.vue

Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
<template>
2+
<main>
3+
<Manage>
4+
<h1>Members</h1>
5+
<Loading v-if="loading" :message="loading" />
6+
<table v-else class="table">
7+
<thead>
8+
<th>Name</th>
9+
<th>Joined</th>
10+
<th>Role</th>
11+
<th></th>
12+
</thead>
13+
<tbody>
14+
<tr v-for="(member, index) in members" :key="`${member.id}_${index}`">
15+
<td>
16+
<img
17+
class="user-image"
18+
alt=""
19+
:src="member.user.profilePicture"
20+
/>
21+
{{ member.user.name }}
22+
</td>
23+
<td><TimeAgo :date="member.createdAt" /></td>
24+
<td>{{ membershipRoles[member.role] || member.role }}</td>
25+
<td class="text text--align-right">
26+
<button
27+
data-balloon="Remove from organization"
28+
data-balloon-pos="up"
29+
class="button button--color-danger button--type-icon"
30+
@click="deleteMembership(membership.id)"
31+
>
32+
<font-awesome-icon
33+
title="Remove from organization"
34+
class="icon icon--color-danger"
35+
icon="trash"
36+
fixed-width
37+
/>
38+
</button>
39+
<button class="button button--color-primary">
40+
Visit &rarr;
41+
</button>
42+
</td>
43+
</tr>
44+
</tbody>
45+
</table>
46+
<h2>Invite another member</h2>
47+
<p>
48+
Use this form to invite another user from your team to this
49+
organization.
50+
</p>
51+
<Loading v-if="inviting" />
52+
<form v-else @submit.prevent="inviteMember">
53+
<Input
54+
:value="newUserName"
55+
label="Name"
56+
placeholder="Enter new user's full name"
57+
required
58+
@input="val => (newUserName = val)"
59+
/>
60+
<Input
61+
:value="newUserEmail"
62+
type="email"
63+
label="Email"
64+
placeholder="Enter new user's email"
65+
required
66+
@input="val => (newUserEmail = val)"
67+
/>
68+
<Select
69+
:value="newUserRole"
70+
label="Role"
71+
:options="membershipRoles"
72+
required
73+
@input="val => (newUserRole = val)"
74+
/>
75+
<button class="button button--color-primary">Send invitation</button>
76+
</form>
77+
</Manage>
78+
</main>
79+
</template>
80+
81+
<script lang="ts">
82+
import { Component, Vue, Watch } from "vue-property-decorator";
83+
import { mapGetters } from "vuex";
84+
import Manage from "@/components/Manage.vue";
85+
import Loading from "@/components/Loading.vue";
86+
import TimeAgo from "@/components/TimeAgo.vue";
87+
import Input from "@/components/form/Input.vue";
88+
import Select from "@/components/form/Select.vue";
89+
import Checkbox from "@/components/form/Checkbox.vue";
90+
import { getAllCountries } from "countries-and-timezones";
91+
import locale from "@/locales/en";
92+
import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome";
93+
import { library } from "@fortawesome/fontawesome-svg-core";
94+
import { faTrash } from "@fortawesome/free-solid-svg-icons";
95+
import { User } from "../../types/auth";
96+
import { Email } from "../../types/settings";
97+
library.add(faTrash);
98+
99+
@Component({
100+
components: {
101+
Manage,
102+
TimeAgo,
103+
Loading,
104+
Input,
105+
Select,
106+
Checkbox,
107+
FontAwesomeIcon
108+
},
109+
computed: mapGetters({
110+
members: "manage/members"
111+
})
112+
})
113+
export default class ManageMembers extends Vue {
114+
members!: any;
115+
loading = "";
116+
inviting = false;
117+
membershipRoles = locale.membershipRoles;
118+
119+
newUserName = "";
120+
newUserEmail = "";
121+
newUserRole = 3;
122+
123+
private mounted() {
124+
this.loading = "Loading members";
125+
this.$store
126+
.dispatch("manage/getMembers")
127+
.then(() => {})
128+
.catch(() => {})
129+
.finally(() => (this.loading = ""));
130+
}
131+
132+
private inviteMember() {
133+
this.inviting = true;
134+
this.$store
135+
.dispatch("manage/inviteMember", {
136+
name: this.newUserName,
137+
email: this.newUserEmail,
138+
role: this.newUserRole
139+
})
140+
.then(() => {})
141+
.catch(() => {})
142+
.finally(() => (this.inviting = false));
143+
}
144+
}
145+
</script>
146+
147+
<style lang="scss" scoped>
148+
.user-image {
149+
height: 2rem;
150+
border-radius: 100%;
151+
width: 2rem;
152+
vertical-align: middle;
153+
margin-right: 0.5rem;
154+
}
155+
</style>

pages/manage/settings.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<template>
22
<main>
33
<Manage>
4-
<h2>Settings</h2>
4+
<h1>Settings</h1>
55
<Loading v-if="loading" :message="loading" />
66
<form v-else @submit.prevent="save">
77
<Input

store/manage.ts

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,20 @@
11
import { MutationTree, ActionTree, GetterTree } from "vuex";
2-
import { RootState, Membership, Organization } from "~/types/manage";
2+
import { RootState, Membership, Organization, Member } from "~/types/manage";
33

4-
export const state = (): RootState => ({});
4+
export const state = (): RootState => ({
5+
members: []
6+
});
57

68
export const mutations: MutationTree<RootState> = {
79
setOrganization(state: RootState, organization: Organization): void {
810
state.organization = organization;
911
},
12+
setMembers(state: RootState, members: Member[]): void {
13+
state.members = members;
14+
},
1015
clearAll(state: RootState): void {
1116
delete state.organization;
17+
delete state.members;
1218
delete state.membership;
1319
}
1420
};
@@ -24,9 +30,23 @@ export const actions: ActionTree<RootState, RootState> = {
2430
if (!state.organization) return;
2531
await this.$axios.patch(`/organizations/${state.organization.id}`, context);
2632
return dispatch("getOrganization", state.organization.id);
33+
},
34+
async getMembers({ rootGetters, commit }) {
35+
const members = (await this.$axios.get(
36+
`/organizations/${rootGetters["auth/activeOrganization"].id}/memberships`
37+
)).data;
38+
commit("setMembers", members);
39+
},
40+
async inviteMember({ dispatch, rootGetters }, context) {
41+
await this.$axios.put(
42+
`/organizations/${rootGetters["auth/activeOrganization"].id}/memberships`,
43+
context
44+
);
45+
return dispatch("getMembers");
2746
}
2847
};
2948

3049
export const getters: GetterTree<RootState, RootState> = {
31-
membership: state => state.membership
50+
membership: state => state.membership,
51+
members: state => state.members
3252
};

types/manage.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,12 @@ export interface Membership {
77
organization: Organization;
88
}
99

10+
export interface Member {
11+
id: number;
12+
}
13+
1014
export interface RootState {
1115
membership?: Membership;
1216
organization?: Organization;
17+
members: Member[];
1318
}

0 commit comments

Comments
 (0)