refactor(dashboard): reorganiza widgets e remove magnet-lines

This commit is contained in:
Felipe Coutinho
2026-03-09 17:12:44 +00:00
parent 3e06a1d056
commit 69da27276c
106 changed files with 6072 additions and 3601 deletions

View File

@@ -0,0 +1,65 @@
import { RiFileList2Line, RiPencilLine } from "@remixicon/react";
import type { Note } from "@/components/anotacoes/types";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import {
buildNoteDisplayTitle,
formatNoteCreatedAt,
getNoteTasksSummary,
} from "@/lib/notes/formatters";
type NoteListItemProps = {
note: Note;
onOpenEdit: (note: Note) => void;
onOpenDetails: (note: Note) => void;
};
export function NoteListItem({
note,
onOpenEdit,
onOpenDetails,
}: NoteListItemProps) {
const displayTitle = buildNoteDisplayTitle(note.title);
const createdAtLabel = formatNoteCreatedAt(note.createdAt);
return (
<li className="flex items-center justify-between gap-2 border-b border-dashed py-2 last:border-b-0 last:pb-0">
<div className="min-w-0 flex-1">
<p className="truncate text-sm font-medium text-foreground">
{displayTitle}
</p>
<div className="mt-1 flex items-center gap-2">
<Badge variant="outline" className="h-5 px-1.5 text-[10px]">
{getNoteTasksSummary(note)}
</Badge>
{createdAtLabel ? (
<p className="truncate text-[11px] text-muted-foreground">
{createdAtLabel}
</p>
) : null}
</div>
</div>
<div className="flex shrink-0 items-center">
<Button
variant="ghost"
size="icon-sm"
className="text-muted-foreground hover:text-foreground"
onClick={() => onOpenEdit(note)}
aria-label={`Editar anotação ${displayTitle}`}
>
<RiPencilLine className="size-4" />
</Button>
<Button
variant="ghost"
size="icon-sm"
className="text-muted-foreground hover:text-foreground"
onClick={() => onOpenDetails(note)}
aria-label={`Ver detalhes da anotação ${displayTitle}`}
>
<RiFileList2Line className="size-4" />
</Button>
</div>
</li>
);
}

View File

@@ -0,0 +1,39 @@
import { RiTodoLine } from "@remixicon/react";
import type { Note } from "@/components/anotacoes/types";
import { WidgetEmptyState } from "@/components/shared/widget-empty-state";
import { NoteListItem } from "./note-list-item";
type NotesListProps = {
notes: Note[];
onOpenEdit: (note: Note) => void;
onOpenDetails: (note: Note) => void;
};
export function NotesList({
notes,
onOpenEdit,
onOpenDetails,
}: NotesListProps) {
if (notes.length === 0) {
return (
<WidgetEmptyState
icon={<RiTodoLine className="size-6 text-muted-foreground" />}
title="Nenhuma anotação ativa"
description="Crie anotações para acompanhar lembretes e tarefas financeiras."
/>
);
}
return (
<ul className="flex flex-col">
{notes.map((note) => (
<NoteListItem
key={note.id}
note={note}
onOpenEdit={onOpenEdit}
onOpenDetails={onOpenDetails}
/>
))}
</ul>
);
}

View File

@@ -0,0 +1,38 @@
import { NoteDetailsDialog } from "@/components/anotacoes/note-details-dialog";
import { NoteDialog } from "@/components/anotacoes/note-dialog";
import type { Note } from "@/components/anotacoes/types";
type NotesWidgetDialogsProps = {
noteToEdit: Note | null;
isEditOpen: boolean;
noteDetails: Note | null;
isDetailsOpen: boolean;
onEditOpenChange: (open: boolean) => void;
onDetailsOpenChange: (open: boolean) => void;
};
export function NotesWidgetDialogs({
noteToEdit,
isEditOpen,
noteDetails,
isDetailsOpen,
onEditOpenChange,
onDetailsOpenChange,
}: NotesWidgetDialogsProps) {
return (
<>
<NoteDialog
mode="update"
note={noteToEdit ?? undefined}
open={isEditOpen}
onOpenChange={onEditOpenChange}
/>
<NoteDetailsDialog
note={noteDetails}
open={isDetailsOpen}
onOpenChange={onDetailsOpenChange}
/>
</>
);
}

View File

@@ -0,0 +1,48 @@
import type { Note } from "@/components/anotacoes/types";
import { NotesList } from "./notes-list";
import { NotesWidgetDialogs } from "./notes-widget-dialogs";
type NotesWidgetViewProps = {
notes: Note[];
noteToEdit: Note | null;
isEditOpen: boolean;
noteDetails: Note | null;
isDetailsOpen: boolean;
onOpenEdit: (note: Note) => void;
onOpenDetails: (note: Note) => void;
onEditOpenChange: (open: boolean) => void;
onDetailsOpenChange: (open: boolean) => void;
};
export function NotesWidgetView({
notes,
noteToEdit,
isEditOpen,
noteDetails,
isDetailsOpen,
onOpenEdit,
onOpenDetails,
onEditOpenChange,
onDetailsOpenChange,
}: NotesWidgetViewProps) {
return (
<>
<div className="flex flex-col gap-4 px-0">
<NotesList
notes={notes}
onOpenEdit={onOpenEdit}
onOpenDetails={onOpenDetails}
/>
</div>
<NotesWidgetDialogs
noteToEdit={noteToEdit}
isEditOpen={isEditOpen}
noteDetails={noteDetails}
isDetailsOpen={isDetailsOpen}
onEditOpenChange={onEditOpenChange}
onDetailsOpenChange={onDetailsOpenChange}
/>
</>
);
}