mirror of
https://github.com/felipegcoutinho/openmonetis.git
synced 2026-03-10 04:51:47 +00:00
refactor(ui): unificar páginas ativas/arquivadas com tabs (v1.3.1)
Substitui rotas separadas de inativos/arquivados por tabs inline em Cartões, Contas e Anotações, seguindo o padrão já usado em Categorias. Remove sub-links da sidebar e padroniza nomenclatura para "Arquivados". Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -10,6 +10,7 @@ import {
|
||||
import { ConfirmActionDialog } from "@/components/confirm-action-dialog";
|
||||
import { EmptyState } from "@/components/empty-state";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
||||
import { Card } from "../ui/card";
|
||||
import { NoteCard } from "./note-card";
|
||||
import { NoteDetailsDialog } from "./note-details-dialog";
|
||||
@@ -18,10 +19,11 @@ import type { Note } from "./types";
|
||||
|
||||
interface NotesPageProps {
|
||||
notes: Note[];
|
||||
isArquivadas?: boolean;
|
||||
archivedNotes: Note[];
|
||||
}
|
||||
|
||||
export function NotesPage({ notes, isArquivadas = false }: NotesPageProps) {
|
||||
export function NotesPage({ notes, archivedNotes }: NotesPageProps) {
|
||||
const [activeTab, setActiveTab] = useState("ativas");
|
||||
const [createOpen, setCreateOpen] = useState(false);
|
||||
const [editOpen, setEditOpen] = useState(false);
|
||||
const [noteToEdit, setNoteToEdit] = useState<Note | null>(null);
|
||||
@@ -32,15 +34,23 @@ export function NotesPage({ notes, isArquivadas = false }: NotesPageProps) {
|
||||
const [arquivarOpen, setArquivarOpen] = useState(false);
|
||||
const [noteToArquivar, setNoteToArquivar] = useState<Note | null>(null);
|
||||
|
||||
const sortedNotes = useMemo(
|
||||
() =>
|
||||
[...notes].sort(
|
||||
const sortNotes = useCallback(
|
||||
(list: Note[]) =>
|
||||
[...list].sort(
|
||||
(a, b) =>
|
||||
new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime(),
|
||||
),
|
||||
[notes],
|
||||
[],
|
||||
);
|
||||
|
||||
const sortedNotes = useMemo(() => sortNotes(notes), [notes, sortNotes]);
|
||||
const sortedArchivedNotes = useMemo(
|
||||
() => sortNotes(archivedNotes),
|
||||
[archivedNotes, sortNotes],
|
||||
);
|
||||
|
||||
const isArquivadas = activeTab === "arquivadas";
|
||||
|
||||
const handleCreateOpenChange = useCallback((open: boolean) => {
|
||||
setCreateOpen(open);
|
||||
}, []);
|
||||
@@ -146,56 +156,75 @@ export function NotesPage({ notes, isArquivadas = false }: NotesPageProps) {
|
||||
? "Desarquivar anotação?"
|
||||
: "Arquivar anotação?";
|
||||
|
||||
const renderNoteList = (list: Note[], isArchived: boolean) => {
|
||||
if (list.length === 0) {
|
||||
return (
|
||||
<Card className="flex min-h-[50vh] w-full items-center justify-center py-12">
|
||||
<EmptyState
|
||||
media={<RiTodoLine className="size-6 text-primary" />}
|
||||
title={
|
||||
isArchived
|
||||
? "Nenhuma anotação arquivada"
|
||||
: "Nenhuma anotação registrada"
|
||||
}
|
||||
description={
|
||||
isArchived
|
||||
? "As anotações arquivadas aparecerão aqui."
|
||||
: "Crie anotações personalizadas para acompanhar lembretes, decisões ou observações financeiras importantes."
|
||||
}
|
||||
/>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="flex flex-wrap gap-4">
|
||||
{list.map((note) => (
|
||||
<NoteCard
|
||||
key={note.id}
|
||||
note={note}
|
||||
onEdit={handleEditRequest}
|
||||
onDetails={handleDetailsRequest}
|
||||
onRemove={handleRemoveRequest}
|
||||
onArquivar={handleArquivarRequest}
|
||||
isArquivadas={isArchived}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="flex w-full flex-col gap-6">
|
||||
{!isArquivadas && (
|
||||
<div className="flex justify-start">
|
||||
<NoteDialog
|
||||
mode="create"
|
||||
open={createOpen}
|
||||
onOpenChange={handleCreateOpenChange}
|
||||
trigger={
|
||||
<Button>
|
||||
<RiAddCircleLine className="size-4" />
|
||||
Nova anotação
|
||||
</Button>
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
<div className="flex justify-start">
|
||||
<NoteDialog
|
||||
mode="create"
|
||||
open={createOpen}
|
||||
onOpenChange={handleCreateOpenChange}
|
||||
trigger={
|
||||
<Button>
|
||||
<RiAddCircleLine className="size-4" />
|
||||
Nova anotação
|
||||
</Button>
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{sortedNotes.length === 0 ? (
|
||||
<Card className="flex min-h-[50vh] w-full items-center justify-center py-12">
|
||||
<EmptyState
|
||||
media={<RiTodoLine className="size-6 text-primary" />}
|
||||
title={
|
||||
isArquivadas
|
||||
? "Nenhuma anotação arquivada"
|
||||
: "Nenhuma anotação registrada"
|
||||
}
|
||||
description={
|
||||
isArquivadas
|
||||
? "As anotações arquivadas aparecerão aqui."
|
||||
: "Crie anotações personalizadas para acompanhar lembretes, decisões ou observações financeiras importantes."
|
||||
}
|
||||
/>
|
||||
</Card>
|
||||
) : (
|
||||
<div className="flex flex-wrap gap-4">
|
||||
{sortedNotes.map((note) => (
|
||||
<NoteCard
|
||||
key={note.id}
|
||||
note={note}
|
||||
onEdit={handleEditRequest}
|
||||
onDetails={handleDetailsRequest}
|
||||
onRemove={handleRemoveRequest}
|
||||
onArquivar={handleArquivarRequest}
|
||||
isArquivadas={isArquivadas}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
<Tabs value={activeTab} onValueChange={setActiveTab} className="w-full">
|
||||
<TabsList>
|
||||
<TabsTrigger value="ativas">Ativas</TabsTrigger>
|
||||
<TabsTrigger value="arquivadas">Arquivadas</TabsTrigger>
|
||||
</TabsList>
|
||||
|
||||
<TabsContent value="ativas" className="mt-4">
|
||||
{renderNoteList(sortedNotes, false)}
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent value="arquivadas" className="mt-4">
|
||||
{renderNoteList(sortedArchivedNotes, true)}
|
||||
</TabsContent>
|
||||
</Tabs>
|
||||
</div>
|
||||
|
||||
<NoteDialog
|
||||
|
||||
@@ -9,6 +9,7 @@ import { ConfirmActionDialog } from "@/components/confirm-action-dialog";
|
||||
import { EmptyState } from "@/components/empty-state";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Card } from "@/components/ui/card";
|
||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
||||
import { CardDialog } from "./card-dialog";
|
||||
import { CardItem } from "./card-item";
|
||||
|
||||
@@ -19,39 +20,36 @@ type AccountOption = {
|
||||
|
||||
interface CardsPageProps {
|
||||
cards: Card[];
|
||||
archivedCards: Card[];
|
||||
accounts: AccountOption[];
|
||||
logoOptions: string[];
|
||||
isInativos?: boolean;
|
||||
}
|
||||
|
||||
export function CardsPage({
|
||||
cards,
|
||||
archivedCards,
|
||||
accounts,
|
||||
logoOptions,
|
||||
isInativos = false,
|
||||
}: CardsPageProps) {
|
||||
const router = useRouter();
|
||||
const [activeTab, setActiveTab] = useState("ativos");
|
||||
const [editOpen, setEditOpen] = useState(false);
|
||||
const [selectedCard, setSelectedCard] = useState<Card | null>(null);
|
||||
const [removeOpen, setRemoveOpen] = useState(false);
|
||||
const [cardToRemove, setCardToRemove] = useState<Card | null>(null);
|
||||
|
||||
const hasCards = cards.length > 0;
|
||||
const sortCards = useCallback(
|
||||
(list: Card[]) =>
|
||||
[...list].sort((a, b) =>
|
||||
a.name.localeCompare(b.name, "pt-BR", { sensitivity: "base" }),
|
||||
),
|
||||
[],
|
||||
);
|
||||
|
||||
const orderedCards = useMemo(
|
||||
() =>
|
||||
[...cards].sort((a, b) => {
|
||||
// Coloca inativos no final
|
||||
const aIsInactive = a.status?.toLowerCase() === "inativo";
|
||||
const bIsInactive = b.status?.toLowerCase() === "inativo";
|
||||
|
||||
if (aIsInactive && !bIsInactive) return 1;
|
||||
if (!aIsInactive && bIsInactive) return -1;
|
||||
|
||||
// Mesma ordem alfabética dentro de cada grupo
|
||||
return a.name.localeCompare(b.name, "pt-BR", { sensitivity: "base" });
|
||||
}),
|
||||
[cards],
|
||||
const orderedCards = useMemo(() => sortCards(cards), [cards, sortCards]);
|
||||
const orderedArchivedCards = useMemo(
|
||||
() => sortCards(archivedCards),
|
||||
[archivedCards, sortCards],
|
||||
);
|
||||
|
||||
const handleEdit = useCallback((card: Card) => {
|
||||
@@ -105,64 +103,83 @@ export function CardsPage({
|
||||
? `Remover cartão "${cardToRemove.name}"?`
|
||||
: "Remover cartão?";
|
||||
|
||||
const renderCardList = (list: Card[], isArchived: boolean) => {
|
||||
if (list.length === 0) {
|
||||
return (
|
||||
<Card className="flex w-full items-center justify-center py-12">
|
||||
<EmptyState
|
||||
media={<RiBankCard2Line className="size-6 text-primary" />}
|
||||
title={
|
||||
isArchived
|
||||
? "Nenhum cartão arquivado"
|
||||
: "Nenhum cartão cadastrado"
|
||||
}
|
||||
description={
|
||||
isArchived
|
||||
? "Os cartões arquivados aparecerão aqui."
|
||||
: "Adicione seu primeiro cartão para acompanhar limites e faturas com mais controle."
|
||||
}
|
||||
/>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="flex flex-wrap gap-4">
|
||||
{list.map((card) => (
|
||||
<CardItem
|
||||
key={card.id}
|
||||
name={card.name}
|
||||
brand={card.brand}
|
||||
status={card.status}
|
||||
closingDay={card.closingDay}
|
||||
dueDay={card.dueDay}
|
||||
limit={card.limit}
|
||||
limitInUse={card.limitInUse ?? null}
|
||||
limitAvailable={card.limitAvailable ?? card.limit ?? null}
|
||||
contaName={card.contaName}
|
||||
logo={card.logo}
|
||||
note={card.note}
|
||||
onEdit={() => handleEdit(card)}
|
||||
onInvoice={() => handleInvoice(card)}
|
||||
onRemove={() => handleRemoveRequest(card)}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="flex w-full flex-col gap-6">
|
||||
{!isInativos && (
|
||||
<div className="flex justify-start">
|
||||
<CardDialog
|
||||
mode="create"
|
||||
accounts={accounts}
|
||||
logoOptions={logoOptions}
|
||||
trigger={
|
||||
<Button>
|
||||
<RiAddCircleLine className="size-4" />
|
||||
Novo cartão
|
||||
</Button>
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
<div className="flex justify-start">
|
||||
<CardDialog
|
||||
mode="create"
|
||||
accounts={accounts}
|
||||
logoOptions={logoOptions}
|
||||
trigger={
|
||||
<Button>
|
||||
<RiAddCircleLine className="size-4" />
|
||||
Novo cartão
|
||||
</Button>
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{hasCards ? (
|
||||
<div className="flex flex-wrap gap-4">
|
||||
{orderedCards.map((card) => (
|
||||
<CardItem
|
||||
key={card.id}
|
||||
name={card.name}
|
||||
brand={card.brand}
|
||||
status={card.status}
|
||||
closingDay={card.closingDay}
|
||||
dueDay={card.dueDay}
|
||||
limit={card.limit}
|
||||
limitInUse={card.limitInUse ?? null}
|
||||
limitAvailable={card.limitAvailable ?? card.limit ?? null}
|
||||
contaName={card.contaName}
|
||||
logo={card.logo}
|
||||
note={card.note}
|
||||
onEdit={() => handleEdit(card)}
|
||||
onInvoice={() => handleInvoice(card)}
|
||||
onRemove={() => handleRemoveRequest(card)}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
) : (
|
||||
<Card className="flex w-full items-center justify-center py-12">
|
||||
<EmptyState
|
||||
media={<RiBankCard2Line className="size-6 text-primary" />}
|
||||
title={
|
||||
isInativos
|
||||
? "Nenhum cartão inativo"
|
||||
: "Nenhum cartão cadastrado"
|
||||
}
|
||||
description={
|
||||
isInativos
|
||||
? "Os cartões inativos aparecerão aqui."
|
||||
: "Adicione seu primeiro cartão para acompanhar limites e faturas com mais controle."
|
||||
}
|
||||
/>
|
||||
</Card>
|
||||
)}
|
||||
<Tabs value={activeTab} onValueChange={setActiveTab} className="w-full">
|
||||
<TabsList>
|
||||
<TabsTrigger value="ativos">Ativos</TabsTrigger>
|
||||
<TabsTrigger value="arquivados">Arquivados</TabsTrigger>
|
||||
</TabsList>
|
||||
|
||||
<TabsContent value="ativos" className="mt-4">
|
||||
{renderCardList(orderedCards, false)}
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent value="arquivados" className="mt-4">
|
||||
{renderCardList(orderedArchivedCards, true)}
|
||||
</TabsContent>
|
||||
</Tabs>
|
||||
</div>
|
||||
|
||||
<CardDialog
|
||||
|
||||
@@ -10,6 +10,7 @@ import { ConfirmActionDialog } from "@/components/confirm-action-dialog";
|
||||
import { AccountCard } from "@/components/contas/account-card";
|
||||
import { EmptyState } from "@/components/empty-state";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
||||
import { getCurrentPeriod } from "@/lib/utils/period";
|
||||
import { Card } from "../ui/card";
|
||||
import { AccountDialog } from "./account-dialog";
|
||||
@@ -18,8 +19,8 @@ import type { Account } from "./types";
|
||||
|
||||
interface AccountsPageProps {
|
||||
accounts: Account[];
|
||||
archivedAccounts: Account[];
|
||||
logoOptions: string[];
|
||||
isInativos?: boolean;
|
||||
}
|
||||
|
||||
const resolveLogoSrc = (logo: string | null) => {
|
||||
@@ -33,10 +34,11 @@ const resolveLogoSrc = (logo: string | null) => {
|
||||
|
||||
export function AccountsPage({
|
||||
accounts,
|
||||
archivedAccounts,
|
||||
logoOptions,
|
||||
isInativos = false,
|
||||
}: AccountsPageProps) {
|
||||
const router = useRouter();
|
||||
const [activeTab, setActiveTab] = useState("ativos");
|
||||
const [editOpen, setEditOpen] = useState(false);
|
||||
const [selectedAccount, setSelectedAccount] = useState<Account | null>(null);
|
||||
const [removeOpen, setRemoveOpen] = useState(false);
|
||||
@@ -45,19 +47,13 @@ export function AccountsPage({
|
||||
const [transferFromAccount, setTransferFromAccount] =
|
||||
useState<Account | null>(null);
|
||||
|
||||
const hasAccounts = accounts.length > 0;
|
||||
const sortAccounts = (list: Account[]) =>
|
||||
[...list].sort((a, b) =>
|
||||
a.name.localeCompare(b.name, "pt-BR", { sensitivity: "base" }),
|
||||
);
|
||||
|
||||
const orderedAccounts = [...accounts].sort((a, b) => {
|
||||
// Coloca inativas no final
|
||||
const aIsInactive = a.status?.toLowerCase() === "inativa";
|
||||
const bIsInactive = b.status?.toLowerCase() === "inativa";
|
||||
|
||||
if (aIsInactive && !bIsInactive) return 1;
|
||||
if (!aIsInactive && bIsInactive) return -1;
|
||||
|
||||
// Mesma ordem alfabética dentro de cada grupo
|
||||
return a.name.localeCompare(b.name, "pt-BR", { sensitivity: "base" });
|
||||
});
|
||||
const orderedAccounts = sortAccounts(accounts);
|
||||
const orderedArchivedAccounts = sortAccounts(archivedAccounts);
|
||||
|
||||
const handleEdit = (account: Account) => {
|
||||
setSelectedAccount(account);
|
||||
@@ -115,6 +111,67 @@ export function AccountsPage({
|
||||
? `Remover conta "${accountToRemove.name}"?`
|
||||
: "Remover conta?";
|
||||
|
||||
const renderAccountList = (list: Account[], isArchived: boolean) => {
|
||||
if (list.length === 0) {
|
||||
return (
|
||||
<Card className="flex min-h-[50vh] w-full items-center justify-center py-12">
|
||||
<EmptyState
|
||||
media={<RiBankLine className="size-6 text-primary" />}
|
||||
title={
|
||||
isArchived
|
||||
? "Nenhuma conta arquivada"
|
||||
: "Nenhuma conta cadastrada"
|
||||
}
|
||||
description={
|
||||
isArchived
|
||||
? "As contas arquivadas aparecerão aqui."
|
||||
: "Cadastre sua primeira conta para começar a organizar os lançamentos."
|
||||
}
|
||||
/>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="flex flex-wrap gap-4">
|
||||
{list.map((account) => {
|
||||
const logoSrc = resolveLogoSrc(account.logo);
|
||||
|
||||
return (
|
||||
<AccountCard
|
||||
key={account.id}
|
||||
accountName={account.name}
|
||||
accountType={`${account.accountType}`}
|
||||
balance={account.balance ?? account.initialBalance ?? 0}
|
||||
status={account.status}
|
||||
excludeFromBalance={account.excludeFromBalance}
|
||||
excludeInitialBalanceFromIncome={
|
||||
account.excludeInitialBalanceFromIncome
|
||||
}
|
||||
icon={
|
||||
logoSrc ? (
|
||||
<Image
|
||||
src={logoSrc}
|
||||
alt={`Logo da conta ${account.name}`}
|
||||
width={42}
|
||||
height={42}
|
||||
className="rounded-lg"
|
||||
/>
|
||||
) : undefined
|
||||
}
|
||||
onEdit={() => handleEdit(account)}
|
||||
onRemove={() => handleRemoveRequest(account)}
|
||||
onTransfer={() => handleTransferRequest(account)}
|
||||
onViewStatement={() =>
|
||||
router.push(`/contas/${account.id}/extrato`)
|
||||
}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="flex w-full flex-col gap-6">
|
||||
@@ -131,60 +188,20 @@ export function AccountsPage({
|
||||
/>
|
||||
</div>
|
||||
|
||||
{hasAccounts ? (
|
||||
<div className="flex flex-wrap gap-4">
|
||||
{orderedAccounts.map((account) => {
|
||||
const logoSrc = resolveLogoSrc(account.logo);
|
||||
<Tabs value={activeTab} onValueChange={setActiveTab} className="w-full">
|
||||
<TabsList>
|
||||
<TabsTrigger value="ativos">Ativas</TabsTrigger>
|
||||
<TabsTrigger value="arquivados">Arquivadas</TabsTrigger>
|
||||
</TabsList>
|
||||
|
||||
return (
|
||||
<AccountCard
|
||||
key={account.id}
|
||||
accountName={account.name}
|
||||
accountType={`${account.accountType}`}
|
||||
balance={account.balance ?? account.initialBalance ?? 0}
|
||||
status={account.status}
|
||||
excludeFromBalance={account.excludeFromBalance}
|
||||
excludeInitialBalanceFromIncome={
|
||||
account.excludeInitialBalanceFromIncome
|
||||
}
|
||||
icon={
|
||||
logoSrc ? (
|
||||
<Image
|
||||
src={logoSrc}
|
||||
alt={`Logo da conta ${account.name}`}
|
||||
width={42}
|
||||
height={42}
|
||||
className="rounded-lg"
|
||||
/>
|
||||
) : undefined
|
||||
}
|
||||
onEdit={() => handleEdit(account)}
|
||||
onRemove={() => handleRemoveRequest(account)}
|
||||
onTransfer={() => handleTransferRequest(account)}
|
||||
onViewStatement={() =>
|
||||
router.push(`/contas/${account.id}/extrato`)
|
||||
}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
) : (
|
||||
<Card className="flex min-h-[50vh] w-full items-center justify-center py-12">
|
||||
<EmptyState
|
||||
media={<RiBankLine className="size-6 text-primary" />}
|
||||
title={
|
||||
isInativos
|
||||
? "Nenhuma conta inativa"
|
||||
: "Nenhuma conta cadastrada"
|
||||
}
|
||||
description={
|
||||
isInativos
|
||||
? "Não há contas inativas no momento."
|
||||
: "Cadastre sua primeira conta para começar a organizar os lançamentos."
|
||||
}
|
||||
/>
|
||||
</Card>
|
||||
)}
|
||||
<TabsContent value="ativos" className="mt-4">
|
||||
{renderAccountList(orderedAccounts, false)}
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent value="arquivados" className="mt-4">
|
||||
{renderAccountList(orderedArchivedAccounts, true)}
|
||||
</TabsContent>
|
||||
</Tabs>
|
||||
</div>
|
||||
|
||||
<AccountDialog
|
||||
|
||||
@@ -1,17 +1,14 @@
|
||||
import {
|
||||
type RemixiconComponentType,
|
||||
RiArchiveLine,
|
||||
RiArrowLeftRightLine,
|
||||
RiBankCard2Line,
|
||||
RiBankLine,
|
||||
RiCalendarEventLine,
|
||||
RiDashboardLine,
|
||||
RiEyeOffLine,
|
||||
RiFileChartLine,
|
||||
RiFundsLine,
|
||||
RiGroupLine,
|
||||
RiInboxLine,
|
||||
RiNoCreditCardLine,
|
||||
RiPriceTag3Line,
|
||||
RiSettings2Line,
|
||||
RiSparklingLine,
|
||||
@@ -116,27 +113,11 @@ export function createSidebarNavData(
|
||||
title: "Cartões",
|
||||
url: "/cartoes",
|
||||
icon: RiBankCard2Line,
|
||||
items: [
|
||||
{
|
||||
title: "Inativos",
|
||||
url: "/cartoes/inativos",
|
||||
key: "cartoes-inativos",
|
||||
icon: RiNoCreditCardLine,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: "Contas",
|
||||
url: "/contas",
|
||||
icon: RiBankLine,
|
||||
items: [
|
||||
{
|
||||
title: "Inativas",
|
||||
url: "/contas/inativos",
|
||||
key: "contas-inativos",
|
||||
icon: RiEyeOffLine,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: "Orçamentos",
|
||||
@@ -163,14 +144,6 @@ export function createSidebarNavData(
|
||||
title: "Anotações",
|
||||
url: "/anotacoes",
|
||||
icon: RiTodoLine,
|
||||
items: [
|
||||
{
|
||||
title: "Arquivadas",
|
||||
url: "/anotacoes/arquivadas",
|
||||
key: "anotacoes-arquivadas",
|
||||
icon: RiArchiveLine,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user