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:
@@ -130,6 +130,7 @@ interface LancamentosFiltersProps {
|
||||
contaCartaoOptions: ContaCartaoFilterOption[];
|
||||
className?: string;
|
||||
exportButton?: ReactNode;
|
||||
hideAdvancedFilters?: boolean;
|
||||
}
|
||||
|
||||
export function LancamentosFilters({
|
||||
@@ -138,6 +139,7 @@ export function LancamentosFilters({
|
||||
contaCartaoOptions,
|
||||
className,
|
||||
exportButton,
|
||||
hideAdvancedFilters = false,
|
||||
}: LancamentosFiltersProps) {
|
||||
const router = useRouter();
|
||||
const pathname = usePathname();
|
||||
@@ -277,22 +279,31 @@ export function LancamentosFilters({
|
||||
|
||||
return (
|
||||
<div className={cn("flex flex-wrap items-center gap-2", className)}>
|
||||
<Input
|
||||
value={searchValue}
|
||||
onChange={(event) => setSearchValue(event.target.value)}
|
||||
placeholder="Buscar"
|
||||
aria-label="Buscar lançamentos"
|
||||
className="w-[250px] text-sm border-dashed"
|
||||
/>
|
||||
|
||||
{exportButton}
|
||||
|
||||
<Drawer direction="right" open={drawerOpen} onOpenChange={setDrawerOpen}>
|
||||
<DrawerTrigger asChild>
|
||||
<Button
|
||||
variant="outline"
|
||||
className="text-sm border-dashed relative"
|
||||
aria-label="Abrir filtros"
|
||||
>
|
||||
<RiFilter3Line className="size-4" />
|
||||
Filtros
|
||||
{hasActiveFilters && (
|
||||
<span className="absolute -top-1 -right-1 size-2 rounded-full bg-primary" />
|
||||
)}
|
||||
</Button>
|
||||
</DrawerTrigger>
|
||||
{!hideAdvancedFilters && (
|
||||
<Drawer direction="right" open={drawerOpen} onOpenChange={setDrawerOpen}>
|
||||
<DrawerTrigger asChild>
|
||||
<Button
|
||||
variant="outline"
|
||||
className="text-sm border-dashed relative"
|
||||
aria-label="Abrir filtros"
|
||||
>
|
||||
<RiFilter3Line className="size-4" />
|
||||
Filtros
|
||||
{hasActiveFilters && (
|
||||
<span className="absolute -top-1 -right-1 size-2 rounded-full bg-primary" />
|
||||
)}
|
||||
</Button>
|
||||
</DrawerTrigger>
|
||||
<DrawerContent>
|
||||
<DrawerHeader>
|
||||
<DrawerTitle>Filtros</DrawerTitle>
|
||||
@@ -319,7 +330,9 @@ export function LancamentosFilters({
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<label className="text-sm font-medium">Condição</label>
|
||||
<label className="text-sm font-medium">
|
||||
Condição de Lançamento
|
||||
</label>
|
||||
<FilterSelect
|
||||
param="condicao"
|
||||
placeholder="Todas"
|
||||
@@ -335,7 +348,7 @@ export function LancamentosFilters({
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<label className="text-sm font-medium">Pagamento</label>
|
||||
<label className="text-sm font-medium">Forma de Pagamento</label>
|
||||
<FilterSelect
|
||||
param="pagamento"
|
||||
placeholder="Todos"
|
||||
@@ -532,15 +545,8 @@ export function LancamentosFilters({
|
||||
</Button>
|
||||
</DrawerFooter>
|
||||
</DrawerContent>
|
||||
</Drawer>
|
||||
|
||||
<Input
|
||||
value={searchValue}
|
||||
onChange={(event) => setSearchValue(event.target.value)}
|
||||
placeholder="Buscar"
|
||||
aria-label="Buscar lançamentos"
|
||||
className="w-[250px] text-sm border-dashed"
|
||||
/>
|
||||
</Drawer>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -734,9 +734,8 @@ export function LancamentosTable({
|
||||
0
|
||||
);
|
||||
|
||||
// Check if all data belongs to current user to determine if filters should be shown
|
||||
const isOwnData = data.every((item) => item.userId === currentUserId);
|
||||
const shouldShowFilters = showFilters && isOwnData;
|
||||
// Check if there's any data from other users
|
||||
const hasOtherUserData = data.some((item) => item.userId !== currentUserId);
|
||||
|
||||
const handleBulkDelete = () => {
|
||||
if (onBulkDelete && selectedCount > 0) {
|
||||
@@ -755,7 +754,7 @@ export function LancamentosTable({
|
||||
};
|
||||
|
||||
const showTopControls =
|
||||
Boolean(onCreate) || Boolean(onMassAdd) || shouldShowFilters;
|
||||
Boolean(onCreate) || Boolean(onMassAdd) || showFilters;
|
||||
|
||||
return (
|
||||
<TooltipProvider>
|
||||
@@ -791,15 +790,16 @@ export function LancamentosTable({
|
||||
) : null}
|
||||
</div>
|
||||
) : (
|
||||
<span className={shouldShowFilters ? "hidden sm:block" : ""} />
|
||||
<span className={showFilters ? "hidden sm:block" : ""} />
|
||||
)}
|
||||
|
||||
{shouldShowFilters ? (
|
||||
{showFilters ? (
|
||||
<LancamentosFilters
|
||||
pagadorOptions={pagadorFilterOptions}
|
||||
categoriaOptions={categoriaFilterOptions}
|
||||
contaCartaoOptions={contaCartaoFilterOptions}
|
||||
className="w-full lg:flex-1 lg:justify-end"
|
||||
hideAdvancedFilters={hasOtherUserData}
|
||||
exportButton={
|
||||
selectedPeriod ? (
|
||||
<LancamentosExport
|
||||
|
||||
Reference in New Issue
Block a user