"use client"; import { useState } from "react"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger, } from "@/components/ui/dialog"; import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, } from "@/components/ui/alert-dialog"; import { Badge } from "@/components/ui/badge"; import { Card, CardContent } from "@/components/ui/card"; import { RiSmartphoneLine, RiDeleteBinLine, RiAddLine, RiFileCopyLine, RiCheckLine, RiAlertLine, } from "@remixicon/react"; import { formatDistanceToNow } from "date-fns"; import { ptBR } from "date-fns/locale"; import { createApiTokenAction, revokeApiTokenAction } from "@/app/(dashboard)/ajustes/actions"; interface ApiToken { id: string; name: string; tokenPrefix: string; lastUsedAt: Date | null; lastUsedIp: string | null; createdAt: Date; expiresAt: Date | null; revokedAt: Date | null; } interface ApiTokensFormProps { tokens: ApiToken[]; } export function ApiTokensForm({ tokens }: ApiTokensFormProps) { const [isCreateOpen, setIsCreateOpen] = useState(false); const [tokenName, setTokenName] = useState(""); const [isCreating, setIsCreating] = useState(false); const [newToken, setNewToken] = useState(null); const [copied, setCopied] = useState(false); const [revokeId, setRevokeId] = useState(null); const [isRevoking, setIsRevoking] = useState(false); const [error, setError] = useState(null); const activeTokens = tokens.filter((t) => !t.revokedAt); const handleCreate = async () => { if (!tokenName.trim()) return; setIsCreating(true); setError(null); try { const result = await createApiTokenAction({ name: tokenName.trim() }); if (result.success && result.data?.token) { setNewToken(result.data.token); setTokenName(""); } else { setError(result.error || "Erro ao criar token"); } } catch { setError("Erro ao criar token"); } finally { setIsCreating(false); } }; const handleCopy = async () => { if (!newToken) return; try { await navigator.clipboard.writeText(newToken); setCopied(true); setTimeout(() => setCopied(false), 2000); } catch { // Fallback for browsers that don't support clipboard API const textArea = document.createElement("textarea"); textArea.value = newToken; document.body.appendChild(textArea); textArea.select(); document.execCommand("copy"); document.body.removeChild(textArea); setCopied(true); setTimeout(() => setCopied(false), 2000); } }; const handleRevoke = async () => { if (!revokeId) return; setIsRevoking(true); try { const result = await revokeApiTokenAction({ tokenId: revokeId }); if (!result.success) { setError(result.error || "Erro ao revogar token"); } } catch { setError("Erro ao revogar token"); } finally { setIsRevoking(false); setRevokeId(null); } }; const handleCloseCreate = () => { setIsCreateOpen(false); setNewToken(null); setTokenName(""); setError(null); }; return (

Dispositivos conectados

Gerencie os dispositivos que podem enviar notificações para o OpenSheets.

{ if (!open) handleCloseCreate(); else setIsCreateOpen(true); }}> {!newToken ? ( <> Criar Token de API Crie um token para conectar o OpenSheets Companion no seu dispositivo Android.
setTokenName(e.target.value)} onKeyDown={(e) => { if (e.key === "Enter") handleCreate(); }} />
{error && (
{error}
)}
) : ( <> Token Criado Copie o token abaixo e cole no app OpenSheets Companion. Este token não será exibido novamente.

Importante:

  • Guarde este token em local seguro
  • Ele não será exibido novamente
  • Use-o para configurar o app Android
)}
{activeTokens.length === 0 ? (

Nenhum dispositivo conectado.

Crie um token para conectar o app OpenSheets Companion.

) : (
{activeTokens.map((token) => (
{token.name} {token.tokenPrefix}...
{token.lastUsedAt ? ( Usado{" "} {formatDistanceToNow(token.lastUsedAt, { addSuffix: true, locale: ptBR, })} {token.lastUsedIp && ( ({token.lastUsedIp}) )} ) : ( Nunca usado )}
Criado em{" "} {new Date(token.createdAt).toLocaleDateString("pt-BR")}
))}
)} {/* Revoke Confirmation Dialog */} !open && setRevokeId(null)}> Revogar token? O dispositivo associado a este token será desconectado e não poderá mais enviar notificações. Esta ação não pode ser desfeita. Cancelar {isRevoking ? "Revogando..." : "Revogar"}
); }