Projeto bot pontos
This commit is contained in:
97
web/app/(painel)/usuarios/page.tsx
Normal file
97
web/app/(painel)/usuarios/page.tsx
Normal file
@@ -0,0 +1,97 @@
|
||||
import Link from "next/link";
|
||||
import { redirect } from "next/navigation";
|
||||
import { apiGet } from "@/lib/server-api";
|
||||
import { badgeClass, pauseReasonLabel, userStatusLabel } from "@/lib/format";
|
||||
import { isRestricted } from "@/lib/access";
|
||||
import type { Me, UserSummary } from "@/lib/types";
|
||||
|
||||
type Search = Promise<Record<string, string | string[] | undefined>>;
|
||||
|
||||
export default async function UsersPage({ searchParams }: { searchParams: Search }) {
|
||||
const me = await apiGet<Me>("/auth/me");
|
||||
if (isRestricted(me.account)) redirect(`/usuarios/${me.account.user_id}`);
|
||||
const sp = await searchParams;
|
||||
const params = new URLSearchParams();
|
||||
for (const key of ["status", "q", "custom_window"]) {
|
||||
const v = sp[key];
|
||||
if (typeof v === "string" && v) params.set(key, v);
|
||||
}
|
||||
const { users } = await apiGet<{ users: UserSummary[] }>(`/users?${params}`);
|
||||
|
||||
return (
|
||||
<>
|
||||
<h1>Usuários</h1>
|
||||
<form className="filters" method="get">
|
||||
<input name="q" placeholder="Nome ou chat ID" defaultValue={typeof sp.q === "string" ? sp.q : ""} />
|
||||
<select name="status" defaultValue={typeof sp.status === "string" ? sp.status : ""}>
|
||||
<option value="">Todos os status</option>
|
||||
<option value="pending">Aguardando aprovação</option>
|
||||
<option value="active">Ativos</option>
|
||||
<option value="disabled">Desativados</option>
|
||||
</select>
|
||||
<select name="custom_window" defaultValue={typeof sp.custom_window === "string" ? sp.custom_window : ""}>
|
||||
<option value="">Qualquer janela</option>
|
||||
<option value="true">Janela personalizada</option>
|
||||
<option value="false">Janela global</option>
|
||||
</select>
|
||||
<button className="btn secondary" type="submit">
|
||||
Filtrar
|
||||
</button>
|
||||
</form>
|
||||
|
||||
<div className="table-wrap">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>Nome</th>
|
||||
<th>Status</th>
|
||||
<th>Credencial</th>
|
||||
<th>Lembretes</th>
|
||||
<th>Janela</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{users.length === 0 && (
|
||||
<tr>
|
||||
<td colSpan={6} className="muted">
|
||||
Nenhum usuário encontrado.
|
||||
</td>
|
||||
</tr>
|
||||
)}
|
||||
{users.map((u) => (
|
||||
<tr key={u.id}>
|
||||
<td>{u.id}</td>
|
||||
<td>
|
||||
<Link href={`/usuarios/${u.id}`}>{u.display_name}</Link>
|
||||
{u.is_bot_admin && <span className="badge"> admin do bot</span>}
|
||||
</td>
|
||||
<td>
|
||||
<span className={badgeClass(u.status)}>{userStatusLabel[u.status]}</span>
|
||||
</td>
|
||||
<td>
|
||||
{!u.has_credential ? (
|
||||
<span className="badge warn">não configurada</span>
|
||||
) : u.credential_validated ? (
|
||||
<span className="badge ok">validada</span>
|
||||
) : (
|
||||
<span className="badge warn">não validada</span>
|
||||
)}
|
||||
{u.consecutive_failures > 0 && <span className="badge error"> {u.consecutive_failures} falha(s)</span>}
|
||||
</td>
|
||||
<td>
|
||||
{u.notifications_enabled ? (
|
||||
<span className="badge ok">ligados</span>
|
||||
) : (
|
||||
<span className="muted">{u.paused_reason ? pauseReasonLabel[u.paused_reason] : "desligados"}</span>
|
||||
)}
|
||||
</td>
|
||||
<td>{u.custom_window ? <span className="badge warn">personalizada</span> : <span className="muted">global</span>}</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user