waveform/components/friends/AllFriendsTab.tsx

97 lines
3.7 KiB
TypeScript

/**
* @file components/friends/AllFriendsTab.tsx
* @description Component rendering the list of all accepted friends along with status indicators, messaging options, and remove actions.
*/
"use client";
import { MessageSquare, X } from "lucide-react";
import { UserAvatar } from "../ui/UserAvatar";
import { Friendship, FriendUser } from "./FriendsView";
/**
* Properties for the AllFriendsTab component.
*
* @interface AllFriendsTabProps
* @property {Friendship[]} acceptedFriends - Array of accepted friendship objects.
* @property {(f: Friendship) => FriendUser} getFriendUser - Helper function to retrieve user details from a friendship relationship.
* @property {(id: string) => void} onRemove - Callback function to remove a friend by their friendship ID.
*/
interface AllFriendsTabProps {
acceptedFriends: Friendship[];
getFriendUser: (f: Friendship) => FriendUser;
onRemove: (id: string) => void;
}
/**
* Renders the list of all accepted friends along with status, message, and remove actions.
*
* @param {AllFriendsTabProps} props - The component props.
* @param {Friendship[]} props.acceptedFriends - Array of accepted friendship objects.
* @param {(f: Friendship) => FriendUser} props.getFriendUser - Helper function to extract user details.
* @param {(id: string) => void} props.onRemove - Callback function to remove a friend.
* @returns {JSX.Element} The rendered list of all accepted friends.
*/
export function AllFriendsTab({
acceptedFriends,
getFriendUser,
onRemove,
}: AllFriendsTabProps) {
return (
<div>
<h3 className="text-xs font-semibold text-muted uppercase tracking-wider mb-3">
All Friends {acceptedFriends.length}
</h3>
{acceptedFriends.length === 0 ? (
<p className="text-sm text-muted">You have no friends yet.</p>
) : (
<div className="space-y-1">
{acceptedFriends.map((f) => {
const friend = getFriendUser(f);
const isOnline = friend.status && friend.status !== "OFFLINE";
return (
<div
key={f.id}
className="flex items-center justify-between p-2.5 rounded-lg hover:bg-surface/50 border-t border-muted/10 group cursor-pointer"
>
<div className="flex items-center gap-3 min-w-0 pr-2">
<div className="relative shrink-0">
<UserAvatar user={friend} size="md" />
</div>
<div className="min-w-0">
<div className="text-sm font-medium text-foreground truncate">
{friend.username}
</div>
<div className="text-xs text-muted truncate">
{isOnline ? "Online" : "Offline"}
</div>
</div>
</div>
<div className="flex items-center gap-1 sm:gap-2 shrink-0">
<button
type="button"
title="Message"
className="p-2 rounded-full bg-surface hover:bg-muted/30 text-muted hover:text-foreground transition-colors cursor-pointer"
>
<MessageSquare className="w-4 h-4" />
</button>
<button
type="button"
onClick={() => onRemove(f.id)}
title="Remove Friend"
className="p-2 rounded-full bg-surface hover:bg-destructive text-muted hover:text-foreground transition-colors cursor-pointer"
>
<X className="w-4 h-4" />
</button>
</div>
</div>
);
})}
</div>
)}
</div>
);
}