Skip to content

Commit bba532b

Browse files
committed
add concept of user roles
1 parent a71886d commit bba532b

File tree

6 files changed

+35
-22
lines changed

6 files changed

+35
-22
lines changed

src/components/ui/members/member-card.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { Trash2 } from "lucide-react";
66
import { CoachingRelationshipWithUserNames } from "@/types/coaching_relationship_with_user_names";
77
import { OrganizationStateStore } from "@/lib/stores/organization-state-store";
88
import { AuthStore } from "@/lib/stores/auth-store";
9-
import { Id } from "@/types/general";
9+
import { Id, Role } from "@/types/general";
1010

1111
interface MemberCardProps {
1212
firstName: string;
@@ -32,10 +32,10 @@ export function MemberCard({
3232
const { deleteNested: deleteUser } = useUserMutation(currentOrganizationId);
3333

3434
// Check if current user is a coach in any of this user's relationships
35-
// and make sure we can't delete ourselves
36-
const canDeleteUser = userRelationships.some(
35+
// and make sure we can't delete ourselves. Admins can delete any user.
36+
const canDeleteUser = userRelationships?.some(
3737
(rel) => rel.coach_id === userSession.id && userId !== userSession.id
38-
);
38+
) || userSession.role === Role.Admin;
3939

4040
const handleDelete = async () => {
4141
if (!confirm("Are you sure you want to delete this member?")) {

src/components/ui/members/member-container.tsx

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { MemberList } from "./member-list";
22
import { AddMemberButton } from "./add-member-button";
33
import { User } from "@/types/user";
4+
import { Role } from "@/types/general";
45
import { CoachingRelationshipWithUserNames } from "@/types/coaching_relationship_with_user_names";
56
import { UserSession } from "@/types/user-session";
67

@@ -22,26 +23,27 @@ export function MemberContainer({
2223
/// Force the AddMemberDialog to open
2324
openAddMemberDialog,
2425
}: MemberContainerProps) {
25-
// Check if current user is a coach in any relationship
26-
const isCoachInAnyRelationship = relationships.some(
27-
(rel) => rel.coach_id === userSession.id
28-
);
29-
30-
// Find relationships where current user is either coach or coachee
31-
const userRelationships = relationships.filter(
32-
(rel) =>
33-
rel.coach_id === userSession.id || rel.coachee_id === userSession.id
34-
);
26+
// Check if current user is a coach in any relationship
27+
const isCoachInAnyRelationship = relationships.some(
28+
(rel) => rel.coach_id === userSession.id
29+
);
30+
31+
// Find relationships where current user is either coach or coachee
32+
const userRelationships = relationships.filter(
33+
(rel) =>
34+
rel.coach_id === userSession.id || rel.coachee_id === userSession.id
35+
);
3536

3637
// Get IDs of users in these relationships
3738
const associatedUserIds = new Set(
3839
userRelationships.flatMap((rel) => [rel.coach_id, rel.coachee_id])
3940
);
4041

41-
// Filter users to only include those in the relationships
42-
const associatedUsers = users.filter((user) =>
43-
associatedUserIds.has(user.id)
44-
);
42+
// If the current user is an admin, show all users. Otherwise, only show users
43+
// that are associated with the current user in a coaching relationship.
44+
const displayUsers = (userSession.role === Role.Admin) ? users : users.filter((user) =>
45+
associatedUserIds.has(user.id)
46+
);
4547

4648
if (isLoading) {
4749
return (
@@ -54,17 +56,17 @@ export function MemberContainer({
5456
<div className="flex justify-between items-center">
5557
<h3 className="text-2xl font-semibold">Members</h3>
5658
{/* Only show the button if user is a coach to _some_ user within the
57-
scope of the organization. We may come back and add this directly to user
59+
scope of the organization or if user is an admin. We may come back and add this directly to user
5860
data. */}
59-
{isCoachInAnyRelationship && (
61+
{(isCoachInAnyRelationship || userSession.role === Role.Admin) && (
6062
<AddMemberButton
6163
onMemberAdded={onRefresh}
6264
openAddMemberDialog={openAddMemberDialog}
6365
/>
6466
)}
6567
</div>
6668
<MemberList
67-
users={associatedUsers}
69+
users={displayUsers}
6870
relationships={userRelationships}
6971
onRefresh={onRefresh}
7072
/>

src/components/ui/members/profile-info-update-form.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ export function ProfileInfoUpdateForm({ user, onSubmit, isSubmitting }: ProfileI
1919
first_name: user.first_name,
2020
last_name: user.last_name,
2121
display_name: user.display_name,
22+
role: user.role,
2223
})
2324
const [errors, setErrors] = useState<Record<string, string>>({})
2425

src/types/general.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,11 @@ export enum ItemStatus {
111111
WontDo = "WontDo",
112112
}
113113

114+
export enum Role {
115+
User = "User",
116+
Admin = "Admin"
117+
}
118+
114119
export function stringToActionStatus(statusString: string): ItemStatus {
115120
const status = statusString.trim();
116121

src/types/user-session.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { User } from "@/types/user";
2+
import { Role } from "@/types/general";
23
/**
34
* This is an intersection type that combines the User type with additional properties.
45
* Currently, it does not add any new properties, but it can be extended in the future
@@ -26,6 +27,7 @@ export function defaultUserSession(): UserSession {
2627
first_name: "",
2728
last_name: "",
2829
display_name: "",
30+
role: Role.User
2931
};
3032
}
3133

src/types/user.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Id } from "@/types/general";
1+
import { Id, Role } from "@/types/general";
22

33
// This must always reflect the Rust struct on the backend entity::users::Model
44
export interface User {
@@ -8,6 +8,7 @@ export interface User {
88
first_name: string;
99
last_name: string;
1010
display_name: string;
11+
role: Role;
1112
}
1213

1314
export interface NewUser {
@@ -35,6 +36,7 @@ export function parseUser(data: unknown): User {
3536
first_name: data.first_name,
3637
last_name: data.last_name,
3738
display_name: data.display_name,
39+
role: data.role,
3840
};
3941
}
4042

@@ -62,6 +64,7 @@ export function defaultUser(): User {
6264
first_name: "",
6365
last_name: "",
6466
display_name: "",
67+
role: Role.User,
6568
};
6669
}
6770

0 commit comments

Comments
 (0)