gh_UserManager/apps/web/app/admin/invitations/page.tsx
bermooda-company 54d5891edf user
2026-08-23 23:59:14 +03:30

103 lines
3.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"use client";
import { useEffect, useState } from "react";
import { RefreshCw, Mail } from "lucide-react";
import { AdminLayout } from "@/components/admin/admin-layout";
import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";
import { useLanguage } from "@/components/language-provider";
interface Invitation {
id: string;
organization_name: string;
email: string;
role: string;
status: string;
created_at: string;
}
export default function AdminInvitationsPage() {
const { lang } = useLanguage();
const [invitations, setInvitations] = useState<Invitation[]>([]);
const [loading, setLoading] = useState(true);
useEffect(() => {
const token = localStorage.getItem("access_token");
if (!token) {
window.location.href = "/login?redirect=/admin/invitations";
return;
}
const fetchData = async () => {
const baseURL = process.env.NEXT_PUBLIC_API_URL;
try {
const res = await fetch(`${baseURL}/membership/invitations/`, {
headers: { Authorization: `Bearer ${token}` },
});
const data = await res.json();
setInvitations(data.results || []);
} catch (e) {
console.error(e);
} finally {
setLoading(false);
}
};
fetchData();
}, []);
const t = (fa: string, en: string) => (lang === "fa" ? fa : en);
if (loading) {
return (
<AdminLayout>
<div className="flex items-center justify-center h-64">
<RefreshCw className="h-8 w-8 animate-spin text-brand-400" />
</div>
</AdminLayout>
);
}
return (
<AdminLayout>
<div className="space-y-6">
<h2 className="text-xl font-bold text-white">{t("دعوت\u200cها", "Invitations")}</h2>
<div className="overflow-x-auto rounded-xl border border-white/10">
<table className="w-full text-sm">
<thead>
<tr className="border-b border-white/10 bg-white/[0.02]">
<th className="px-4 py-3 text-start text-xs font-medium text-slate-400">{t("ایمیل", "Email")}</th>
<th className="px-4 py-3 text-start text-xs font-medium text-slate-400">{t("سازمان", "Organization")}</th>
<th className="px-4 py-3 text-start text-xs font-medium text-slate-400">{t("نقش", "Role")}</th>
<th className="px-4 py-3 text-start text-xs font-medium text-slate-400">{t("وضعیت", "Status")}</th>
</tr>
</thead>
<tbody>
{invitations.map((inv) => (
<tr key={inv.id} className="border-b border-white/5">
<td className="px-4 py-3 text-white">{inv.email}</td>
<td className="px-4 py-3 text-slate-300">{inv.organization_name}</td>
<td className="px-4 py-3">
<Badge variant="secondary" className="text-xs capitalize">{inv.role}</Badge>
</td>
<td className="px-4 py-3">
<Badge variant={inv.status === "pending" ? "default" : "secondary"} className="text-xs">
{inv.status}
</Badge>
</td>
</tr>
))}
</tbody>
</table>
{invitations.length === 0 && !loading && (
<div className="py-12 text-center text-slate-500">
{t("دعوتی یافت نشد", "No invitations found")}
</div>
)}
</div>
</div>
</AdminLayout>
);
}