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
This commit is contained in:
121
components/pagadores/pagador-card.tsx
Normal file
121
components/pagadores/pagador-card.tsx
Normal file
@@ -0,0 +1,121 @@
|
||||
"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>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user