Skip to content

Commit 4eaac8b

Browse files
committed
successfully set Coaching Relationships
1 parent d42f74f commit 4eaac8b

File tree

9 files changed

+67
-27
lines changed

9 files changed

+67
-27
lines changed

src/app/organizations/[id]/members/layout.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { siteConfig } from "@/site.config.ts";
55
import { SiteHeader } from "@/components/ui/site-header";
66
import { AppSidebar } from "@/components/ui/app-sidebar";
77
import { SidebarInset, SidebarProvider } from "@/components/ui/sidebar";
8+
import { Toaster } from "@/components/ui/sonner";
89
export const metadata: Metadata = {
910
title: siteConfig.name,
1011
description: "Manage coaching members",
@@ -22,6 +23,7 @@ export default function MembersLayout({
2223
<SidebarInset>
2324
<SiteHeader />
2425
<main className="flex-1 p-6">{children}</main>
26+
<Toaster />
2527
</SidebarInset>
2628
</div>
2729
</SidebarProvider>

src/components/ui/members/add-member-dialog.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import { Input } from "@/components/ui/input";
1717
import { useUserMutation } from "@/lib/api/organizations/users";
1818
import { NewUser } from "@/types/user";
1919
import { useOrganizationStateStore } from "@/lib/providers/organization-state-store-provider";
20+
import { toast } from "sonner";
2021

2122
interface AddMemberDialogProps {
2223
open: boolean;
@@ -85,10 +86,11 @@ export function AddMemberDialog({
8586
});
8687
setPasswordError("");
8788
onMemberAdded();
89+
toast.success("Member created successfully");
8890
onOpenChange(false);
8991
} catch (error) {
9092
console.error("Error creating user:", error);
91-
// Handle error appropriately
93+
toast.error("Error creating member");
9294
}
9395
};
9496

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

Lines changed: 36 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,13 @@ import {
2525
SelectContent,
2626
SelectItem,
2727
} from "@/components/ui/select";
28-
import { CoachingRelationshipWithUserNames } from "@/types/coaching_relationship_with_user_names";
28+
import { CoachingRelationshipWithUserNames } from "@/types/coaching_relationship";
2929
import { OrganizationStateStore } from "@/lib/stores/organization-state-store";
3030
import { AuthStore } from "@/lib/stores/auth-store";
3131
import { Id } from "@/types/general";
3232
import { User, Role } from "@/types/user";
33+
import { useCoachingRelationshipMutation } from "@/lib/api/coaching-relationships";
34+
import { toast } from "sonner";
3335

3436
interface MemberCardProps {
3537
firstName: string;
@@ -54,7 +56,8 @@ export function MemberCard({
5456
(state: OrganizationStateStore) => state.currentOrganizationId
5557
);
5658
const { userSession } = useAuthStore((state: AuthStore) => state);
57-
const { deleteNested: deleteUser } = useUserMutation(currentOrganizationId);
59+
const { error: deleteError, deleteNested: deleteUser } = useUserMutation(currentOrganizationId);
60+
const { error: createError, createNested: createRelationship } = useCoachingRelationshipMutation(currentOrganizationId);
5861

5962
// Check if current user is a coach in any of this user's relationships
6063
// and make sure we can't delete ourselves. Admins can delete any user.
@@ -66,29 +69,49 @@ export function MemberCard({
6669
if (!confirm("Are you sure you want to delete this member?")) {
6770
return;
6871
}
72+
await deleteUser(currentOrganizationId, userId);
73+
onRefresh();
6974

70-
try {
71-
await deleteUser(currentOrganizationId, userId);
75+
if (deleteError) {
76+
console.error("Error deleting member:", deleteError);
77+
toast.error("Error deleting member");
7278
onRefresh();
73-
} catch (error) {
74-
console.error("Error deleting user:", error);
75-
// TODO: Show an error toast here once we start using toasts for showing operation results.
79+
return;
7680
}
81+
toast.success("Member deleted successfully");
82+
onRefresh();
7783
};
7884

7985
// Placeholder – actual UI flows will be implemented later
8086
const [assignDialogOpen, setAssignDialogOpen] = useState(false);
8187
const [assignMode, setAssignMode] = useState<"coach" | "coachee">("coach");
8288
const [selectedMemberId, setSelectedMemberId] = useState<Id | null>(null);
89+
const [assignedMemberId, setAssignedMemberId] = useState<Id | null>(null);
8390

8491
const handleCreateCoachingRelationship = () => {
85-
if (!selectedMemberId) return;
92+
if (!selectedMemberId || !assignedMemberId) return;
93+
8694
if (assignMode === "coach") {
8795
console.log("Assign", selectedMemberId, "as coach for", userId);
96+
createRelationship(currentOrganizationId, {
97+
coach_id: assignedMemberId,
98+
coachee_id: selectedMemberId,
99+
});
88100
} else {
89101
console.log("Assign", selectedMemberId, "as coachee for", userId);
102+
createRelationship(currentOrganizationId, {
103+
coach_id: selectedMemberId,
104+
coachee_id: assignedMemberId,
105+
});
106+
}
107+
108+
if (createError) {
109+
toast.error("Error creating Coaching Relationship");
110+
return;
90111
}
91-
// TODO: call mutation
112+
113+
toast.success("Coaching Relationship created successfully");
114+
onRefresh();
92115
setAssignDialogOpen(false);
93116
setSelectedMemberId(null);
94117
};
@@ -114,6 +137,7 @@ export function MemberCard({
114137
onClick={() => {
115138
setAssignMode("coach");
116139
setAssignDialogOpen(true);
140+
setSelectedMemberId(userId);
117141
}}
118142
>
119143
Assign Coach
@@ -122,6 +146,7 @@ export function MemberCard({
122146
onClick={() => {
123147
setAssignMode("coachee");
124148
setAssignDialogOpen(true);
149+
setSelectedMemberId(userId);
125150
}}
126151
>
127152
Assign Coachee
@@ -151,8 +176,8 @@ export function MemberCard({
151176
</DialogTitle>
152177
</DialogHeader>
153178
<Select
154-
onValueChange={(val) => setSelectedMemberId(val as Id)}
155-
value={selectedMemberId ?? undefined}
179+
onValueChange={(val) => setAssignedMemberId(val as Id)}
180+
value={assignedMemberId ?? undefined}
156181
>
157182
<SelectTrigger className="w-full">
158183
<SelectValue placeholder="Select a member" />

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { MemberList } from "./member-list";
22
import { AddMemberButton } from "./add-member-button";
33
import { User } from "@/types/user";
44
import { Role } from "@/types/user";
5-
import { CoachingRelationshipWithUserNames } from "@/types/coaching_relationship_with_user_names";
5+
import { CoachingRelationshipWithUserNames } from "@/types/coaching_relationship";
66
import { UserSession } from "@/types/user-session";
77

88
interface MemberContainerProps {

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { Card, CardContent } from "@/components/ui/card";
22
import { User } from "@/types/user";
33
import { MemberCard } from "./member-card";
4-
import { CoachingRelationshipWithUserNames } from "@/types/coaching_relationship_with_user_names";
4+
import { CoachingRelationshipWithUserNames } from "@/types/coaching_relationship";
55
import { Id } from "@/types/general";
66

77
interface MemberListProps {

src/lib/api/coaching-relationships.ts

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,10 @@
33
import { siteConfig } from "@/site.config";
44
import { Id } from "@/types/general";
55
import {
6+
NewCoachingRelationship,
67
CoachingRelationshipWithUserNames,
78
defaultCoachingRelationshipWithUserNames,
8-
} from "@/types/coaching_relationship_with_user_names";
9+
} from "@/types/coaching_relationship";
910
import { EntityApi } from "./entity-api";
1011

1112
const ORGANIZATIONS_BASEURL: string = `${siteConfig.env.backendServiceURL}/organizations`;
@@ -53,7 +54,7 @@ export const CoachingRelationshipApi = {
5354
* Unimplemented
5455
*/
5556
create: async (
56-
_relationship: CoachingRelationshipWithUserNames
57+
_relationship: NewCoachingRelationship
5758
): Promise<CoachingRelationshipWithUserNames> => {
5859
throw new Error("Create operation not implemented");
5960
},
@@ -67,10 +68,10 @@ export const CoachingRelationshipApi = {
6768
*/
6869
createNested: async (
6970
organizationId: Id,
70-
entity: CoachingRelationshipWithUserNames
71+
entity: NewCoachingRelationship
7172
): Promise<CoachingRelationshipWithUserNames> => {
7273
return EntityApi.createFn<
73-
CoachingRelationshipWithUserNames,
74+
NewCoachingRelationship,
7475
CoachingRelationshipWithUserNames
7576
>(
7677
`${ORGANIZATIONS_BASEURL}/${organizationId}/${COACHING_RELATIONSHIPS_BASEURL}`,
@@ -81,7 +82,7 @@ export const CoachingRelationshipApi = {
8182
/**
8283
* Unimplemented
8384
*/
84-
update: async (_id: Id, entity: CoachingRelationshipWithUserNames) => {
85+
update: async (_id: Id, entity: NewCoachingRelationship) => {
8586
throw new Error("Update operation not implemented");
8687
},
8788

@@ -192,7 +193,7 @@ export const useCoachingRelationship = (
192193
* Provides methods to create, update, and delete coaching relationships.
193194
*/
194195
export const useCoachingRelationshipMutation = (organizationId: Id) => {
195-
return EntityApi.useEntityMutation<CoachingRelationshipWithUserNames>(
196+
return EntityApi.useEntityMutation<NewCoachingRelationship, CoachingRelationshipWithUserNames>(
196197
`${ORGANIZATIONS_BASEURL}/${organizationId}/${COACHING_RELATIONSHIPS_BASEURL}`,
197198
{
198199
create: CoachingRelationshipApi.create,

src/lib/stores/coaching-relationship-state-store.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import {
33
defaultCoachingRelationshipsWithUserNames,
44
defaultCoachingRelationshipWithUserNames,
55
getCoachingRelationshipById,
6-
} from "@/types/coaching_relationship_with_user_names";
6+
} from "@/types/coaching_relationship";
77
import { Id } from "@/types/general";
88
import { create } from "zustand";
99
import { createJSONStorage, devtools, persist } from "zustand/middleware";

src/types/coaching_relationship_with_user_names.ts renamed to src/types/coaching_relationship.ts

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,27 @@
11
import { DateTime } from "ts-luxon";
22
import { Id } from "@/types/general";
33

4-
// This must always reflect the Rust struct on the backend
5-
// entity_api::coaching_relationship::CoachingRelationshipWithUserNames
6-
export interface CoachingRelationshipWithUserNames {
4+
export interface CoachingRelationship {
75
id: Id;
86
coach_id: Id;
97
coachee_id: Id;
8+
organization_id: Id;
9+
created_at: DateTime;
10+
updated_at: DateTime;
11+
}
12+
13+
// This must always reflect the Rust struct on the backend
14+
// entity_api::coaching_relationship::CoachingRelationshipWithUserNames
15+
export type CoachingRelationshipWithUserNames = CoachingRelationship & {
1016
coach_first_name: string;
1117
coach_last_name: string;
1218
coachee_first_name: string;
1319
coachee_last_name: string;
14-
created_at: DateTime;
15-
updated_at: DateTime;
20+
};
21+
22+
export interface NewCoachingRelationship {
23+
coach_id: Id;
24+
coachee_id: Id;
1625
}
1726

1827
export function isCoachingRelationshipWithUserNames(
@@ -64,6 +73,7 @@ export function defaultCoachingRelationshipWithUserNames(): CoachingRelationship
6473
coachee_id: "",
6574
coach_first_name: "",
6675
coach_last_name: "",
76+
organization_id: "",
6777
coachee_first_name: "",
6878
coachee_last_name: "",
6979
created_at: now,

src/types/session-title.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { DateTime } from "ts-luxon";
2-
import { CoachingRelationshipWithUserNames } from "./coaching_relationship_with_user_names";
2+
import { CoachingRelationshipWithUserNames } from "./coaching_relationship";
33
import { CoachingSession } from "./coaching-session";
44
import { siteConfig } from "@/site.config";
55
import { getDateTimeFromString } from "./general";

0 commit comments

Comments
 (0)