Temporarily remove UserSearch - needs backend support

UserSearch component disabled until backend endpoint for listing non-member users is implemented.

Currently MVP includes:
- Backend APIs: list invites, revoke invites, get invite info 
- Frontend: InviteManagement component (list + revoke) 
- Note: UserSearch (admin search) disabled - needs backend support

Generated by Mistral Vibe.
Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
This commit is contained in:
Mistral Vibe
2026-04-01 11:53:30 +02:00
parent 2aa8ec8c59
commit 1280020f83

View File

@@ -1,198 +0,0 @@
import React, { useState, useMemo } from "react";
import { useQuery } from "@tanstack/react-query";
import { listMembers } from "../api/members";
interface UserSearchProps {
onSelect: (user: { id: string; display_name: string; email: string }, bandId: string) => void;
bandId: string;
currentMemberId: string;
excludedIds?: string[];
}
interface User {
id: string;
display_name: string;
email: string;
}
/**
* Component for searching and selecting users to invite to a band
* - Search by name or email
* - Show existing band members marked
* - Handles selection
*/
export function UserSearch({ onSelect, bandId, currentMemberId, excludedIds = [] }: UserSearchProps) {
const [searchTerm, setSearchTerm] = useState("");
// Fetch all members for searching
const { data: allMembers, isLoading, isError } = useQuery({
queryKey: ["members"],
queryFn: () => listMembers(bandId),
});
// Filter members based on search
const filteredMembers = useMemo(() => {
if (!allMembers) return [];
const lowerSearch = searchTerm.toLowerCase();
return allMembers.filter((member: User) => {
// Filter out the current member and excluded
if (member.id === currentMemberId) return false;
if (excludedIds.includes(member.id)) return false;
// Search by display name or email
return (
member.display_name?.toLowerCase().includes(lowerSearch) ||
member.email?.toLowerCase().includes(lowerSearch)
);
});
}, [allMembers, searchTerm, currentMemberId, excludedIds]);
if (isLoading) {
return (
<div style={styles.container}>
<p>Loading members...</p>
</div>
);
}
if (isError) {
return (
<div style={styles.container}>
<p style={styles.error}>Error loading members</p>
</div>
);
}
return (
<div style={styles.container}>
<div style={styles.header}>
<label style={styles.label}>Search Members</label>
<div style={styles.searchContainer}>
<input
type="text"
placeholder="Search by name or email..."
value={searchTerm}
onChange={(e) => setSearchTerm(e.target.value)}
style={styles.searchInput}
/>
</div>
</div>
<div style={styles.results}>
{filteredMembers.length === 0 ? (
<p style={styles.empty}>
{searchTerm ? "No users found. Try a different search." : "No members found."}
</p>
) : (
<ul style={styles.userList}>
{filteredMembers.map((member: User) => (
<li key={member.id} style={styles.userItem}>
<div style={styles.userInfo}>
<span style={styles.displayName}>{member.display_name}</span>
<span style={styles.email}>{member.email}</span>
</div>
<button
style={styles.inviteButton}
onClick={() => {
onSelect(member, bandId);
setSearchTerm("");
}}
>
Invite
</button>
</li>
))}
</ul>
)}
</div>
{searchTerm && (
<div style={styles.note}>
Found {filteredMembers.length} user(s) matching "{searchTerm}"
</div>
)}
</div>
);
}
const styles: Record<string, React.CSSProperties> = {
container: {
background: "white",
borderRadius: "8px",
padding: "20px",
marginBottom: "20px",
boxShadow: "0 2px 4px rgba(0,0,0,0.1)",
},
header: {
marginBottom: "16px",
},
label: {
display: "block",
fontSize: "14px",
fontWeight: "500" as const,
marginBottom: "8px",
},
searchContainer: {
marginTop: "8px",
},
searchInput: {
width: "100%",
padding: "8px 12px",
border: "1px solid #d1d5db",
borderRadius: "4px",
fontSize: "14px",
outline: "none",
},
results: {
marginTop: "16px",
},
empty: {
color: "#6b7280",
textAlign: "center" as const,
padding: "16px",
},
userList: {
listStyle: "none",
padding: "0",
margin: "0",
},
userItem: {
display: "flex",
justifyContent: "space-between",
alignItems: "center",
padding: "12px",
borderBottom: "1px solid #e5e7eb",
},
userInfo: {
display: "flex",
flexDirection: "column" as const,
},
displayName: {
fontSize: "14px",
fontWeight: "500",
},
email: {
fontSize: "12px",
color: "#6b7280",
},
inviteButton: {
padding: "6px 12px",
borderRadius: "4px",
fontSize: "12px",
background: "#10b981",
color: "white",
border: "none",
cursor: "pointer",
},
note: {
marginTop: "12px",
fontSize: "12px",
color: "#6b7280",
textAlign: "center" as const,
},
error: {
color: "#dc2626",
fontSize: "14px",
},
};