AI_Agent_Final / web /src /components /GroupMembers.tsx
SarahXia0405's picture
Upload 73 files
0ef5c60 verified
import React, { useState } from 'react';
import { Users, MailPlus } from 'lucide-react';
import { Badge } from './ui/badge';
import { Button } from './ui/button';
import { Input } from './ui/input';
import { toast } from 'sonner';
import {
Dialog,
DialogContent,
DialogDescription,
DialogFooter,
DialogHeader,
DialogTitle,
} from './ui/dialog';
import clareAvatar from '../assets/dfe44dab3ad8cd93953eac4a3e68bd1a5f999653.png';
import type { GroupMember } from '../App';
interface GroupMembersProps {
members: GroupMember[];
}
export function GroupMembers({ members }: GroupMembersProps) {
const [inviteOpen, setInviteOpen] = useState(false);
const [inviteEmail, setInviteEmail] = useState('');
const handleSendInvite = () => {
if (!inviteEmail.trim()) {
toast.error('Please enter an email to invite');
return;
}
toast.success(`Invitation sent to ${inviteEmail}`);
setInviteEmail('');
setInviteOpen(false);
};
return (
<div className="space-y-3">
<div className="flex items-center justify-between gap-2">
<div className="flex items-center gap-2">
<Users className="h-4 w-4 text-muted-foreground" />
<h3 className="text-sm">Group Members ({members.length})</h3>
</div>
<Button
size="sm"
variant="secondary"
className="h-8 gap-2"
onClick={() => setInviteOpen(true)}
>
<MailPlus className="h-4 w-4" />
<span className="text-xs font-medium">Invite</span>
</Button>
</div>
<div className="space-y-2">
{members.map((member) => {
const isAI = !!member.isAI;
return (
<div
key={member.id}
className="flex items-center gap-3 p-2 rounded-lg hover:bg-muted/50 transition-colors"
>
{/* Avatar */}
<div className={`w-8 h-8 rounded-full flex items-center justify-center flex-shrink-0 ${
isAI
? 'overflow-hidden bg-white'
: 'bg-muted'
}`}>
{isAI ? (
<img src={clareAvatar} alt="Clare" className="w-full h-full object-cover" />
) : (
<span className="text-sm">
{member.name.split(' ').map(n => n[0]).join('').toUpperCase()}
</span>
)}
</div>
{/* Member Info */}
<div className="flex-1 min-w-0">
<div className="flex items-center gap-2">
<p className="text-sm truncate">{member.name}</p>
{isAI && (
<Badge variant="secondary" className="text-xs">AI</Badge>
)}
</div>
<p className="text-xs text-muted-foreground truncate">{member.email}</p>
</div>
{/* Online Status */}
<div className="w-2 h-2 rounded-full bg-green-500 flex-shrink-0" title="Online" />
</div>
)})}
</div>
<Dialog open={inviteOpen} onOpenChange={setInviteOpen}>
<DialogContent className="w-[600px] max-w-[600px] sm:max-w-[600px]" style={{ maxWidth: 600 }}>
<DialogHeader>
<DialogTitle>Invite member</DialogTitle>
<DialogDescription>Send a quick email invite with the team details.</DialogDescription>
</DialogHeader>
<div className="space-y-3">
<Input
type="email"
placeholder="name@example.com"
value={inviteEmail}
onChange={(e) => setInviteEmail(e.target.value)}
/>
<p className="text-xs text-muted-foreground">
An invitation email with a join link will be sent to this address.
</p>
</div>
<DialogFooter>
<Button variant="outline" onClick={() => setInviteOpen(false)}>Cancel</Button>
<Button onClick={handleSendInvite}>Send invite</Button>
</DialogFooter>
</DialogContent>
</Dialog>
</div>
);
}