Enhance Staff Users tab with search and listing
cgen-b0d9945c721c4c1392773fbeab8ce836
This commit is contained in:
parent
16de77fb35
commit
d4bc0af678
1 changed files with 48 additions and 4 deletions
|
|
@ -55,6 +55,8 @@ export default function Staff() {
|
||||||
const [openReports, setOpenReports] = useState<any[]>([]);
|
const [openReports, setOpenReports] = useState<any[]>([]);
|
||||||
const [mentorshipAll, setMentorshipAll] = useState<any[]>([]);
|
const [mentorshipAll, setMentorshipAll] = useState<any[]>([]);
|
||||||
const [loadingData, setLoadingData] = useState(false);
|
const [loadingData, setLoadingData] = useState(false);
|
||||||
|
const [searchQ, setSearchQ] = useState("");
|
||||||
|
const [users, setUsers] = useState<any[]>([]);
|
||||||
|
|
||||||
const refresh = async () => {
|
const refresh = async () => {
|
||||||
setLoadingData(true);
|
setLoadingData(true);
|
||||||
|
|
@ -78,6 +80,19 @@ export default function Staff() {
|
||||||
if (user && hasAccess) refresh();
|
if (user && hasAccess) refresh();
|
||||||
}, [user, hasAccess]);
|
}, [user, hasAccess]);
|
||||||
|
|
||||||
|
const loadUsers = async () => {
|
||||||
|
try {
|
||||||
|
const params = new URLSearchParams();
|
||||||
|
if (searchQ.trim()) params.set("q", searchQ.trim());
|
||||||
|
params.set("limit", "25");
|
||||||
|
const resp = await fetch(`/api/staff/users?${params.toString()}`);
|
||||||
|
const data = resp.ok ? await resp.json() : [];
|
||||||
|
setUsers(Array.isArray(data) ? data : []);
|
||||||
|
} catch {
|
||||||
|
setUsers([]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const updateReportStatus = async (
|
const updateReportStatus = async (
|
||||||
id: string,
|
id: string,
|
||||||
status: "resolved" | "ignored" | "open",
|
status: "resolved" | "ignored" | "open",
|
||||||
|
|
@ -307,10 +322,39 @@ export default function Staff() {
|
||||||
Search, roles, and quick actions
|
Search, roles, and quick actions
|
||||||
</CardDescription>
|
</CardDescription>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardContent>
|
<CardContent className="space-y-4">
|
||||||
<p className="text-sm text-muted-foreground">
|
<div className="flex gap-2">
|
||||||
User tools coming soon.
|
<input
|
||||||
</p>
|
className="w-full rounded border border-border/50 bg-background px-3 py-2 text-sm"
|
||||||
|
placeholder="Search by name or username"
|
||||||
|
value={searchQ}
|
||||||
|
onChange={(e) => setSearchQ(e.target.value)}
|
||||||
|
/>
|
||||||
|
<Button onClick={loadUsers} variant="outline">
|
||||||
|
Search
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
<div className="rounded border border-border/50">
|
||||||
|
{users.length === 0 ? (
|
||||||
|
<p className="p-3 text-sm text-muted-foreground">No users found.</p>
|
||||||
|
) : (
|
||||||
|
<div className="divide-y divide-border/50">
|
||||||
|
{users.map((u) => (
|
||||||
|
<div key={u.id} className="flex items-center justify-between p-3">
|
||||||
|
<div>
|
||||||
|
<div className="text-sm font-medium">
|
||||||
|
{u.full_name || u.username || u.id}
|
||||||
|
</div>
|
||||||
|
<div className="text-xs text-muted-foreground">{u.username}</div>
|
||||||
|
</div>
|
||||||
|
<Badge variant="outline" className="capitalize">
|
||||||
|
{u.user_type || "unknown"}
|
||||||
|
</Badge>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
</TabsContent>
|
</TabsContent>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue