forked from git.gladyson/openmonetis
feat: implementar melhorias em importação, compartilhamento e contas inativas
- Corrigir cálculo de valor na importação de lançamentos parcelados
- Exibir valor total (parcela × quantidade) ao invés do valor da parcela individual
- Permite recriar parcelamentos importados com valor correto
- Permitir que usuários compartilhados se descompartilhem de pagadores
- Adicionar componente PagadorLeaveShareCard na aba Perfil
- Usuário filho pode sair do compartilhamento sem precisar do usuário pai
- Manter autorização bidirecionada na action de remoção de share
- Implementar submenu "Inativos" para contas bancárias
- Criar página /contas/inativos seguindo padrão de cartões
- Filtrar contas ativas e inativas em páginas separadas
- Adicionar ícone e navegação no sidebar
This commit is contained in:
@@ -2,7 +2,7 @@ import MoneyValues from "@/components/money-values";
|
||||
import { WidgetEmptyState } from "@/components/widget-empty-state";
|
||||
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
|
||||
import type { PagadorCardUsageItem } from "@/lib/pagadores/details";
|
||||
import { RiBankCardLine } from "@remixicon/react";
|
||||
import { RiBankCard2Line } from "@remixicon/react";
|
||||
import Image from "next/image";
|
||||
|
||||
const resolveLogoPath = (logo?: string | null) => {
|
||||
@@ -36,7 +36,7 @@ export function PagadorCardUsageCard({ items }: PagadorCardUsageCardProps) {
|
||||
<CardContent className="space-y-3 pt-2">
|
||||
{items.length === 0 ? (
|
||||
<WidgetEmptyState
|
||||
icon={<RiBankCardLine className="size-6 text-muted-foreground" />}
|
||||
icon={<RiBankCard2Line className="size-6 text-muted-foreground" />}
|
||||
title="Nenhum lançamento com cartão de crédito"
|
||||
description="Quando houver despesas registradas com cartão, elas aparecerão aqui."
|
||||
/>
|
||||
|
||||
114
components/pagadores/details/pagador-leave-share-card.tsx
Normal file
114
components/pagadores/details/pagador-leave-share-card.tsx
Normal file
@@ -0,0 +1,114 @@
|
||||
"use client";
|
||||
|
||||
import { deletePagadorShareAction } from "@/app/(dashboard)/pagadores/actions";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
|
||||
import { RiLogoutBoxLine } from "@remixicon/react";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { useState, useTransition } from "react";
|
||||
import { toast } from "sonner";
|
||||
|
||||
interface PagadorLeaveShareCardProps {
|
||||
shareId: string;
|
||||
pagadorName: string;
|
||||
createdAt: string;
|
||||
}
|
||||
|
||||
export function PagadorLeaveShareCard({
|
||||
shareId,
|
||||
pagadorName,
|
||||
createdAt,
|
||||
}: PagadorLeaveShareCardProps) {
|
||||
const router = useRouter();
|
||||
const [isPending, startTransition] = useTransition();
|
||||
const [showConfirm, setShowConfirm] = useState(false);
|
||||
|
||||
const handleLeave = () => {
|
||||
startTransition(async () => {
|
||||
const result = await deletePagadorShareAction({ shareId });
|
||||
|
||||
if (!result.success) {
|
||||
toast.error(result.error);
|
||||
return;
|
||||
}
|
||||
|
||||
toast.success("Você saiu do compartilhamento.");
|
||||
router.push("/pagadores");
|
||||
});
|
||||
};
|
||||
|
||||
const formattedDate = new Date(createdAt).toLocaleDateString("pt-BR", {
|
||||
day: "2-digit",
|
||||
month: "long",
|
||||
year: "numeric",
|
||||
});
|
||||
|
||||
return (
|
||||
<Card className="border">
|
||||
<CardHeader>
|
||||
<CardTitle className="text-base font-semibold">
|
||||
Acesso Compartilhado
|
||||
</CardTitle>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
Você tem acesso somente leitura aos dados de{" "}
|
||||
<strong>{pagadorName}</strong>.
|
||||
</p>
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-4">
|
||||
<div className="flex flex-col gap-2 rounded-lg border border-dashed p-4 text-sm">
|
||||
<span className="text-xs font-semibold uppercase text-muted-foreground/80">
|
||||
Informações do compartilhamento
|
||||
</span>
|
||||
<div className="flex flex-col gap-1">
|
||||
<p className="text-sm">
|
||||
<span className="text-muted-foreground">Acesso desde:</span>{" "}
|
||||
<strong>{formattedDate}</strong>
|
||||
</p>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
Você pode visualizar os lançamentos, mas não pode criar ou editar.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{!showConfirm ? (
|
||||
<Button
|
||||
type="button"
|
||||
variant="outline"
|
||||
onClick={() => setShowConfirm(true)}
|
||||
className="w-full"
|
||||
>
|
||||
<RiLogoutBoxLine className="size-4" />
|
||||
Sair do compartilhamento
|
||||
</Button>
|
||||
) : (
|
||||
<div className="space-y-2">
|
||||
<p className="text-sm font-medium text-destructive">
|
||||
Tem certeza que deseja sair? Você perderá o acesso aos dados de{" "}
|
||||
{pagadorName}.
|
||||
</p>
|
||||
<div className="flex gap-2">
|
||||
<Button
|
||||
type="button"
|
||||
variant="outline"
|
||||
onClick={() => setShowConfirm(false)}
|
||||
disabled={isPending}
|
||||
className="flex-1"
|
||||
>
|
||||
Cancelar
|
||||
</Button>
|
||||
<Button
|
||||
type="button"
|
||||
variant="destructive"
|
||||
onClick={handleLeave}
|
||||
disabled={isPending}
|
||||
className="flex-1"
|
||||
>
|
||||
{isPending ? "Saindo..." : "Confirmar saída"}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</CardContent>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user