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:
210
components/lancamentos/dialogs/lancamento-details-dialog.tsx
Normal file
210
components/lancamentos/dialogs/lancamento-details-dialog.tsx
Normal file
@@ -0,0 +1,210 @@
|
||||
"use client";
|
||||
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import {
|
||||
Card,
|
||||
CardContent,
|
||||
CardDescription,
|
||||
CardHeader,
|
||||
} from "@/components/ui/card";
|
||||
import {
|
||||
Dialog,
|
||||
DialogClose,
|
||||
DialogContent,
|
||||
DialogFooter,
|
||||
DialogTitle,
|
||||
} from "@/components/ui/dialog";
|
||||
import { Separator } from "@/components/ui/separator";
|
||||
import { getPaymentMethodIcon } from "@/lib/utils/icons";
|
||||
import {
|
||||
currencyFormatter,
|
||||
formatCondition,
|
||||
formatDate,
|
||||
formatPeriod,
|
||||
getTransactionBadgeVariant,
|
||||
} from "@/lib/lancamentos/formatting-helpers";
|
||||
import { InstallmentTimeline } from "../shared/installment-timeline";
|
||||
import type { LancamentoItem } from "../types";
|
||||
|
||||
interface LancamentoDetailsDialogProps {
|
||||
open: boolean;
|
||||
onOpenChange: (open: boolean) => void;
|
||||
lancamento: LancamentoItem | null;
|
||||
}
|
||||
|
||||
export function LancamentoDetailsDialog({
|
||||
open,
|
||||
onOpenChange,
|
||||
lancamento,
|
||||
}: LancamentoDetailsDialogProps) {
|
||||
if (!lancamento) return null;
|
||||
|
||||
const isInstallment =
|
||||
lancamento.condition?.toLowerCase() === "parcelado" &&
|
||||
lancamento.currentInstallment &&
|
||||
lancamento.installmentCount;
|
||||
|
||||
const valorParcela = Math.abs(lancamento.amount);
|
||||
const totalParcelas = lancamento.installmentCount ?? 1;
|
||||
const parcelaAtual = lancamento.currentInstallment ?? 1;
|
||||
const valorTotal = isInstallment
|
||||
? valorParcela * totalParcelas
|
||||
: valorParcela;
|
||||
const valorRestante = isInstallment
|
||||
? valorParcela * (totalParcelas - parcelaAtual)
|
||||
: 0;
|
||||
|
||||
return (
|
||||
<Dialog open={open} onOpenChange={onOpenChange}>
|
||||
<DialogContent className="p-0 sm:max-w-xl">
|
||||
<Card className="gap-2 space-y-4">
|
||||
<CardHeader className="flex flex-row items-start border-b">
|
||||
<div>
|
||||
<DialogTitle className="group flex items-center gap-2 text-lg">
|
||||
#{lancamento.id}
|
||||
</DialogTitle>
|
||||
<CardDescription>
|
||||
{formatDate(lancamento.purchaseDate)}
|
||||
</CardDescription>
|
||||
</div>
|
||||
</CardHeader>
|
||||
|
||||
<CardContent className="text-sm">
|
||||
<div className="grid gap-3">
|
||||
<ul className="grid gap-3">
|
||||
<DetailRow label="Descrição" value={lancamento.name} />
|
||||
|
||||
<DetailRow
|
||||
label="Período"
|
||||
value={formatPeriod(lancamento.period)}
|
||||
/>
|
||||
|
||||
<li className="flex items-center justify-between">
|
||||
<span className="text-muted-foreground">
|
||||
Forma de Pagamento
|
||||
</span>
|
||||
<span className="flex items-center gap-1.5">
|
||||
{getPaymentMethodIcon(lancamento.paymentMethod)}
|
||||
<span className="capitalize">
|
||||
{lancamento.paymentMethod}
|
||||
</span>
|
||||
</span>
|
||||
</li>
|
||||
|
||||
<DetailRow
|
||||
label={lancamento.cartaoName ? "Cartão" : "Conta"}
|
||||
value={lancamento.cartaoName ?? lancamento.contaName ?? "—"}
|
||||
/>
|
||||
|
||||
<DetailRow
|
||||
label="Categoria"
|
||||
value={lancamento.categoriaName ?? "—"}
|
||||
/>
|
||||
|
||||
<li className="flex items-center justify-between">
|
||||
<span className="text-muted-foreground">
|
||||
Tipo de Transação
|
||||
</span>
|
||||
<span className="capitalize">
|
||||
<Badge
|
||||
variant={getTransactionBadgeVariant(
|
||||
lancamento.transactionType
|
||||
)}
|
||||
>
|
||||
{lancamento.transactionType}
|
||||
</Badge>
|
||||
</span>
|
||||
</li>
|
||||
|
||||
<DetailRow
|
||||
label="Condição"
|
||||
value={formatCondition(lancamento.condition)}
|
||||
/>
|
||||
|
||||
<li className="flex items-center justify-between">
|
||||
<span className="text-muted-foreground">Responsável</span>
|
||||
<span className="flex items-center gap-2 capitalize">
|
||||
<span>{lancamento.pagadorName}</span>
|
||||
</span>
|
||||
</li>
|
||||
|
||||
<DetailRow
|
||||
label="Status"
|
||||
value={lancamento.isSettled ? "Pago" : "Pendente"}
|
||||
/>
|
||||
|
||||
{lancamento.note && (
|
||||
<DetailRow label="Notas" value={lancamento.note} />
|
||||
)}
|
||||
</ul>
|
||||
|
||||
<ul className="mb-6 grid gap-3">
|
||||
{isInstallment && (
|
||||
<li className="mt-4">
|
||||
<InstallmentTimeline
|
||||
purchaseDate={new Date(lancamento.purchaseDate)}
|
||||
currentInstallment={parcelaAtual}
|
||||
totalInstallments={totalParcelas}
|
||||
period={lancamento.period}
|
||||
/>
|
||||
</li>
|
||||
)}
|
||||
|
||||
<DetailRow
|
||||
label={isInstallment ? "Valor da Parcela" : "Valor"}
|
||||
value={currencyFormatter.format(valorParcela)}
|
||||
/>
|
||||
|
||||
{isInstallment && (
|
||||
<DetailRow
|
||||
label="Valor Restante"
|
||||
value={currencyFormatter.format(valorRestante)}
|
||||
/>
|
||||
)}
|
||||
|
||||
{lancamento.recurrenceCount && (
|
||||
<DetailRow
|
||||
label="Quantidade de Recorrências"
|
||||
value={`${lancamento.recurrenceCount} meses`}
|
||||
/>
|
||||
)}
|
||||
|
||||
{!isInstallment && <Separator className="my-2" />}
|
||||
|
||||
<li className="flex items-center justify-between font-semibold">
|
||||
<span className="text-muted-foreground">Total da Compra</span>
|
||||
<span className="text-lg">
|
||||
{currencyFormatter.format(valorTotal)}
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<DialogFooter>
|
||||
<DialogClose asChild>
|
||||
<Button className="w-full" type="button">
|
||||
Entendi
|
||||
</Button>
|
||||
</DialogClose>
|
||||
</DialogFooter>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
);
|
||||
}
|
||||
|
||||
interface DetailRowProps {
|
||||
label: string;
|
||||
value: string;
|
||||
}
|
||||
|
||||
function DetailRow({ label, value }: DetailRowProps) {
|
||||
return (
|
||||
<li className="flex items-center justify-between">
|
||||
<span className="text-muted-foreground">{label}</span>
|
||||
<span className="capitalize">{value}</span>
|
||||
</li>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user