Files
openmonetis/components/pagadores/pagador-card.tsx
Felipe Coutinho ea0b8618e0 feat: adição de novos ícones SVG e configuração do ambiente
- Adicionados ícones SVG para ChatGPT, Claude, Gemini e OpenRouter
- Implementados ícones para modos claro e escuro do ChatGPT
- Criado script de inicialização para PostgreSQL com extensão pgcrypto
- Adicionado script de configuração de ambiente que faz backup do .env
- Configurado tsconfig.json para TypeScript com opções de compilação
2025-11-15 15:49:36 -03:00

122 lines
3.7 KiB
TypeScript

"use client";
import { Badge } from "@/components/ui/badge";
import { Card } from "@/components/ui/card";
import { PAGADOR_ROLE_ADMIN } from "@/lib/pagadores/constants";
import { getAvatarSrc } from "@/lib/pagadores/utils";
import {
RiDeleteBin5Line,
RiEyeLine,
RiMailSendLine,
RiPencilLine,
RiVerifiedBadgeFill,
} from "@remixicon/react";
import Image from "next/image";
import Link from "next/link";
import { useMemo } from "react";
import type { Pagador } from "./types";
interface PagadorCardProps {
pagador: Pagador;
onEdit?: () => void;
onRemove?: () => void;
}
export function PagadorCard({ pagador, onEdit, onRemove }: PagadorCardProps) {
const avatarSrc = useMemo(
() => getAvatarSrc(pagador.avatarUrl),
[pagador.avatarUrl]
);
const isAdmin = pagador.role === PAGADOR_ROLE_ADMIN;
const isReadOnly = !pagador.canEdit;
return (
<Card className=" overflow-hidden px-6">
{/* Avatar posicionado sobre o header */}
<div className="relative flex flex-col items-start">
<div className="relative mb-3 flex size-16 items-center justify-center overflow-hidden rounded-full border-background bg-background shadow-lg">
<Image
src={avatarSrc}
alt={`Avatar de ${pagador.name}`}
width={80}
height={80}
className="h-full w-full object-cover"
/>
</div>
{/* Nome e badges */}
<div className="flex items-center gap-1.5">
<h3 className="text-base font-semibold text-foreground">
{pagador.name}
</h3>
{isAdmin ? (
<RiVerifiedBadgeFill className="size-4 text-blue-500" aria-hidden />
) : null}
{pagador.isAutoSend ? (
<RiMailSendLine className="size-4 text-primary" aria-hidden />
) : null}
</div>
{/* Email */}
{pagador.email ? (
<p className="mt-1 text-xs text-muted-foreground">{pagador.email}</p>
) : (
<p className="mt-1 text-xs text-muted-foreground">
Sem Email cadastrado
</p>
)}
{/* Status badges */}
<div className="mt-2 flex flex-wrap items-center justify-center gap-1.5">
<Badge
variant={pagador.status === "Ativo" ? "success" : "outline"}
className="text-xs"
>
{pagador.status}
</Badge>
{isReadOnly ? (
<Badge variant="outline" className="text-xs text-amber-600">
Somente leitura
</Badge>
) : null}
</div>
</div>
{/* Footer com links */}
<div className="flex flex-wrap items-start justify-start gap-3 text-sm font-medium">
{!isReadOnly && onEdit ? (
<button
type="button"
onClick={onEdit}
className={`text-primary flex items-center gap-1 font-medium transition-opacity hover:opacity-80`}
>
<RiPencilLine className="size-4" aria-hidden />
editar
</button>
) : null}
<Link
href={`/pagadores/${pagador.id}`}
className={`text-primary flex items-center gap-1 font-medium transition-opacity hover:opacity-80`}
>
<RiEyeLine className="size-4" aria-hidden />
detalhes
</Link>
{!isAdmin && !isReadOnly && onRemove ? (
<button
type="button"
onClick={onRemove}
className={`text-destructive flex items-center gap-1 font-medium transition-opacity hover:opacity-80`}
>
<RiDeleteBin5Line className="size-4" aria-hidden />
remover
</button>
) : null}
</div>
</Card>
);
}