1+ import { useState } from "react" ;
12import { useOrganizationStateStore } from "@/lib/providers/organization-state-store-provider" ;
23import { useAuthStore } from "@/lib/providers/auth-store-provider" ;
34import { useUserMutation } from "@/lib/api/organizations/users" ;
45import { Button } from "@/components/ui/button" ;
5- import { Trash2 } from "lucide-react" ;
6+ import {
7+ DropdownMenu ,
8+ DropdownMenuTrigger ,
9+ DropdownMenuContent ,
10+ DropdownMenuItem ,
11+ DropdownMenuSeparator ,
12+ } from "@/components/ui/dropdown-menu" ;
13+ import { MoreHorizontal , Trash2 } from "lucide-react" ;
14+ import {
15+ Dialog ,
16+ DialogContent ,
17+ DialogHeader ,
18+ DialogFooter ,
19+ DialogTitle ,
20+ } from "@/components/ui/dialog" ;
21+ import {
22+ Select ,
23+ SelectTrigger ,
24+ SelectValue ,
25+ SelectContent ,
26+ SelectItem ,
27+ } from "@/components/ui/select" ;
628import { CoachingRelationshipWithUserNames } from "@/types/coaching_relationship_with_user_names" ;
729import { OrganizationStateStore } from "@/lib/stores/organization-state-store" ;
830import { AuthStore } from "@/lib/stores/auth-store" ;
931import { Id } from "@/types/general" ;
10- import { Role } from "@/types/user" ;
32+ import { User , Role } from "@/types/user" ;
1133
1234interface MemberCardProps {
1335 firstName : string ;
@@ -16,6 +38,7 @@ interface MemberCardProps {
1638 userId : Id ;
1739 userRelationships : CoachingRelationshipWithUserNames [ ] ;
1840 onRefresh : ( ) => void ;
41+ users : User [ ] ;
1942}
2043
2144export function MemberCard ( {
@@ -25,6 +48,7 @@ export function MemberCard({
2548 userId,
2649 userRelationships,
2750 onRefresh,
51+ users,
2852} : MemberCardProps ) {
2953 const currentOrganizationId = useOrganizationStateStore (
3054 ( state : OrganizationStateStore ) => state . currentOrganizationId
@@ -36,7 +60,7 @@ export function MemberCard({
3660 // and make sure we can't delete ourselves. Admins can delete any user.
3761 const canDeleteUser = userRelationships ?. some (
3862 ( rel ) => rel . coach_id === userSession . id && userId !== userSession . id
39- ) || userSession . role === Role . Admin ;
63+ ) || ( userSession . role === Role . Admin && userSession . id !== userId ) ;
4064
4165 const handleDelete = async ( ) => {
4266 if ( ! confirm ( "Are you sure you want to delete this member?" ) ) {
@@ -52,6 +76,23 @@ export function MemberCard({
5276 }
5377 } ;
5478
79+ // Placeholder – actual UI flows will be implemented later
80+ const [ assignDialogOpen , setAssignDialogOpen ] = useState ( false ) ;
81+ const [ assignMode , setAssignMode ] = useState < "coach" | "coachee" > ( "coach" ) ;
82+ const [ selectedMemberId , setSelectedMemberId ] = useState < Id | null > ( null ) ;
83+
84+ const handleCreateCoachingRelationship = ( ) => {
85+ if ( ! selectedMemberId ) return ;
86+ if ( assignMode === "coach" ) {
87+ console . log ( "Assign" , selectedMemberId , "as coach for" , userId ) ;
88+ } else {
89+ console . log ( "Assign" , selectedMemberId , "as coachee for" , userId ) ;
90+ }
91+ // TODO: call mutation
92+ setAssignDialogOpen ( false ) ;
93+ setSelectedMemberId ( null ) ;
94+ } ;
95+
5596 return (
5697 < div className = "flex items-center p-4 hover:bg-accent/50 transition-colors" >
5798 < div className = "flex-1" >
@@ -60,16 +101,75 @@ export function MemberCard({
60101 </ h3 >
61102 { email && < p className = "text-sm text-muted-foreground" > { email } </ p > }
62103 </ div >
63- { canDeleteUser && (
64- < Button
65- variant = "ghost"
66- size = "icon"
67- onClick = { handleDelete }
68- className = "text-destructive hover:text-destructive"
69- >
70- < Trash2 className = "h-4 w-4" />
71- </ Button >
72- ) }
104+ < DropdownMenu >
105+ < DropdownMenuTrigger asChild >
106+ < Button variant = "ghost" size = "icon" className = "text-muted-foreground" >
107+ < MoreHorizontal className = "h-4 w-4" />
108+ </ Button >
109+ </ DropdownMenuTrigger >
110+ < DropdownMenuContent align = "end" >
111+ { userSession . role === Role . Admin && (
112+ < >
113+ < DropdownMenuItem
114+ onClick = { ( ) => {
115+ setAssignMode ( "coach" ) ;
116+ setAssignDialogOpen ( true ) ;
117+ } }
118+ >
119+ Assign Coach
120+ </ DropdownMenuItem >
121+ < DropdownMenuItem
122+ onClick = { ( ) => {
123+ setAssignMode ( "coachee" ) ;
124+ setAssignDialogOpen ( true ) ;
125+ } }
126+ >
127+ Assign Coachee
128+ </ DropdownMenuItem >
129+ </ >
130+ ) }
131+ { canDeleteUser && (
132+ < >
133+ < DropdownMenuSeparator />
134+ < DropdownMenuItem
135+ onClick = { handleDelete }
136+ className = "text-destructive focus:text-destructive"
137+ >
138+ < Trash2 className = "mr-2 h-4 w-4" /> Delete
139+ </ DropdownMenuItem >
140+ </ >
141+ ) }
142+ </ DropdownMenuContent >
143+ </ DropdownMenu >
144+
145+ { /* Assign Coach/Coachee Modal */ }
146+ < Dialog open = { assignDialogOpen } onOpenChange = { setAssignDialogOpen } >
147+ < DialogContent >
148+ < DialogHeader >
149+ < DialogTitle >
150+ { assignMode === "coach" ? "Assign Coach" : "Assign Coachee" }
151+ </ DialogTitle >
152+ </ DialogHeader >
153+ < Select
154+ onValueChange = { ( val ) => setSelectedMemberId ( val as Id ) }
155+ value = { selectedMemberId ?? undefined }
156+ >
157+ < SelectTrigger className = "w-full" >
158+ < SelectValue placeholder = "Select a member" />
159+ </ SelectTrigger >
160+ < SelectContent >
161+ { users
162+ . filter ( ( m ) => m . id !== userId )
163+ . map ( ( m ) => (
164+ < SelectItem key = { m . id } value = { m . id . toString ( ) } > { `${ m . first_name } ${ m . last_name } ` } </ SelectItem >
165+ ) ) }
166+ </ SelectContent >
167+ </ Select >
168+ < DialogFooter >
169+ < Button onClick = { handleCreateCoachingRelationship } > { assignMode === "coach" ? "Assign as Coach" : "Assign as Coachee" } </ Button >
170+ </ DialogFooter >
171+ </ DialogContent >
172+ </ Dialog >
73173 </ div >
74174 ) ;
75175}
0 commit comments