style: padronizar dialogs e aplicar formatação Biome
DialogContent: padding p-6→p-10, max-w-lg→max-w-xl. DialogFooter/AlertDialogFooter: botões com flex-1 (largura igual). Remove gap-3/w-full redundantes de 12+ dialogs. Reformatação Biome: line wrapping, import ordering. Error component renomeado para evitar shadowing do global Error. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -5,9 +5,9 @@ import { revalidatePath } from "next/cache";
|
||||
import { Resend } from "resend";
|
||||
import { z } from "zod";
|
||||
import { lancamentos, pagadores } from "@/db/schema";
|
||||
import { getResendFromEmail } from "@/lib/email/resend";
|
||||
import { getUser } from "@/lib/auth/server";
|
||||
import { db } from "@/lib/db";
|
||||
import { getResendFromEmail } from "@/lib/email/resend";
|
||||
import {
|
||||
fetchPagadorBoletoStats,
|
||||
fetchPagadorCardUsage,
|
||||
|
||||
@@ -14,7 +14,7 @@ import {
|
||||
EmptyTitle,
|
||||
} from "@/components/ui/empty";
|
||||
|
||||
export default function Error({
|
||||
export default function ErrorComponent({
|
||||
error,
|
||||
reset,
|
||||
}: {
|
||||
|
||||
@@ -59,9 +59,10 @@ export function ChangelogTab({ versions }: { versions: ChangelogVersion[] }) {
|
||||
{version.contributor && (
|
||||
<div className="border-t pt-4 mt-4">
|
||||
<span className="text-sm text-muted-foreground">
|
||||
Contribuições:{" "}
|
||||
{(() => {
|
||||
const { label, url } = parseContributorLine(version.contributor);
|
||||
Contribuições: {(() => {
|
||||
const { label, url } = parseContributorLine(
|
||||
version.contributor,
|
||||
);
|
||||
if (url) {
|
||||
return (
|
||||
<Link
|
||||
@@ -74,7 +75,11 @@ export function ChangelogTab({ versions }: { versions: ChangelogVersion[] }) {
|
||||
</Link>
|
||||
);
|
||||
}
|
||||
return <span className="font-medium text-foreground">{label}</span>;
|
||||
return (
|
||||
<span className="font-medium text-foreground">
|
||||
{label}
|
||||
</span>
|
||||
);
|
||||
})()}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
@@ -111,7 +111,7 @@ export function DeleteAccountForm() {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<DialogFooter className="sm:justify-end">
|
||||
<DialogFooter>
|
||||
<Button
|
||||
type="button"
|
||||
variant="outline"
|
||||
|
||||
@@ -1,15 +1,20 @@
|
||||
"use client";
|
||||
|
||||
import {
|
||||
DndContext,
|
||||
closestCenter,
|
||||
DndContext,
|
||||
type DragEndEvent,
|
||||
KeyboardSensor,
|
||||
PointerSensor,
|
||||
useSensor,
|
||||
useSensors,
|
||||
} from "@dnd-kit/core";
|
||||
import { arrayMove, SortableContext, useSortable, verticalListSortingStrategy } from "@dnd-kit/sortable";
|
||||
import {
|
||||
arrayMove,
|
||||
SortableContext,
|
||||
useSortable,
|
||||
verticalListSortingStrategy,
|
||||
} from "@dnd-kit/sortable";
|
||||
import { CSS } from "@dnd-kit/utilities";
|
||||
import { RiDragMove2Line } from "@remixicon/react";
|
||||
import { useRouter } from "next/navigation";
|
||||
@@ -69,7 +74,10 @@ function SortableColumnItem({ id }: { id: string }) {
|
||||
{...attributes}
|
||||
{...listeners}
|
||||
>
|
||||
<RiDragMove2Line className="size-4 shrink-0 text-muted-foreground" aria-hidden />
|
||||
<RiDragMove2Line
|
||||
className="size-4 shrink-0 text-muted-foreground"
|
||||
aria-hidden
|
||||
/>
|
||||
<span>{label}</span>
|
||||
</div>
|
||||
);
|
||||
@@ -86,8 +94,9 @@ export function PreferencesForm({
|
||||
const [isPending, startTransition] = useTransition();
|
||||
const [magnetlinesDisabled, setMagnetlinesDisabled] =
|
||||
useState(disableMagnetlines);
|
||||
const [extratoNoteAsColumn, setExtratoNoteAsColumn] =
|
||||
useState(initialExtratoNoteAsColumn);
|
||||
const [extratoNoteAsColumn, setExtratoNoteAsColumn] = useState(
|
||||
initialExtratoNoteAsColumn,
|
||||
);
|
||||
const [columnOrder, setColumnOrder] = useState<string[]>(
|
||||
initialColumnOrder && initialColumnOrder.length > 0
|
||||
? initialColumnOrder
|
||||
@@ -232,7 +241,8 @@ export function PreferencesForm({
|
||||
<div>
|
||||
<h3 className="text-base font-semibold">Extrato e lançamentos</h3>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
Como exibir anotações e a ordem das colunas na tabela de movimentações.
|
||||
Como exibir anotações e a ordem das colunas na tabela de
|
||||
movimentações.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -242,7 +252,9 @@ export function PreferencesForm({
|
||||
Anotações em coluna
|
||||
</Label>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
Quando ativo, as anotações aparecem em uma coluna na tabela. Quando desativado, aparecem em um balão ao passar o mouse no ícone.
|
||||
Quando ativo, as anotações aparecem em uma coluna na tabela.
|
||||
Quando desativado, aparecem em um balão ao passar o mouse no
|
||||
ícone.
|
||||
</p>
|
||||
</div>
|
||||
<Switch
|
||||
@@ -256,7 +268,8 @@ export function PreferencesForm({
|
||||
<div className="space-y-2 max-w-md">
|
||||
<Label className="text-base">Ordem das colunas</Label>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
Arraste os itens para definir a ordem em que as colunas aparecem na tabela do extrato e dos lançamentos.
|
||||
Arraste os itens para definir a ordem em que as colunas aparecem na
|
||||
tabela do extrato e dos lançamentos.
|
||||
</p>
|
||||
<DndContext
|
||||
sensors={sensors}
|
||||
|
||||
@@ -194,7 +194,7 @@ export function EventModal({ open, day, onClose, onCreate }: EventModalProps) {
|
||||
)}
|
||||
</div>
|
||||
|
||||
<DialogFooter className="flex justify-end gap-2">
|
||||
<DialogFooter>
|
||||
<Button variant="outline" onClick={onClose}>
|
||||
Cancelar
|
||||
</Button>
|
||||
|
||||
@@ -241,7 +241,7 @@ export function CardDialog({
|
||||
<p className="text-sm text-destructive">{errorMessage}</p>
|
||||
)}
|
||||
|
||||
<DialogFooter className="gap-3">
|
||||
<DialogFooter>
|
||||
<Button
|
||||
type="button"
|
||||
variant="outline"
|
||||
|
||||
@@ -85,7 +85,7 @@ export function CategoryDialog({
|
||||
setFormState(initialState);
|
||||
setErrorMessage(null);
|
||||
}
|
||||
}, [dialogOpen, setFormState, category, defaultType]);
|
||||
}, [dialogOpen, setFormState, initialState]);
|
||||
|
||||
// Clear error when dialog closes
|
||||
useEffect(() => {
|
||||
@@ -156,7 +156,7 @@ export function CategoryDialog({
|
||||
<p className="text-sm text-destructive">{errorMessage}</p>
|
||||
)}
|
||||
|
||||
<DialogFooter className="gap-3">
|
||||
<DialogFooter>
|
||||
<Button
|
||||
type="button"
|
||||
variant="outline"
|
||||
|
||||
@@ -14,7 +14,6 @@ import {
|
||||
AlertDialogTrigger,
|
||||
} from "@/components/ui/alert-dialog";
|
||||
import { buttonVariants } from "@/components/ui/button";
|
||||
import { cn } from "@/lib/utils/ui";
|
||||
|
||||
interface ConfirmActionDialogProps {
|
||||
trigger?: React.ReactNode;
|
||||
@@ -87,19 +86,13 @@ export function ConfirmActionDialog({
|
||||
) : null}
|
||||
</AlertDialogHeader>
|
||||
<AlertDialogFooter>
|
||||
<AlertDialogCancel
|
||||
disabled={isPending || disabled}
|
||||
className="w-full sm:w-auto"
|
||||
>
|
||||
<AlertDialogCancel disabled={isPending || disabled}>
|
||||
{cancelLabel}
|
||||
</AlertDialogCancel>
|
||||
<AlertDialogAction
|
||||
onClick={handleConfirm}
|
||||
disabled={isPending || disabled}
|
||||
className={cn(
|
||||
buttonVariants({ variant: confirmVariant }),
|
||||
"w-full sm:w-auto",
|
||||
)}
|
||||
className={buttonVariants({ variant: confirmVariant })}
|
||||
>
|
||||
{isPending ? resolvedPendingLabel : confirmLabel}
|
||||
</AlertDialogAction>
|
||||
|
||||
@@ -261,7 +261,7 @@ export function AccountDialog({
|
||||
<p className="text-sm text-destructive">{errorMessage}</p>
|
||||
)}
|
||||
|
||||
<DialogFooter className="gap-3">
|
||||
<DialogFooter>
|
||||
<Button
|
||||
type="button"
|
||||
variant="outline"
|
||||
|
||||
@@ -230,7 +230,7 @@ export function TransferDialog({
|
||||
<p className="text-sm text-destructive">{errorMessage}</p>
|
||||
)}
|
||||
|
||||
<DialogFooter className="gap-3">
|
||||
<DialogFooter>
|
||||
<Button
|
||||
type="button"
|
||||
variant="outline"
|
||||
|
||||
@@ -394,7 +394,7 @@ export function AnticipateInstallmentsDialog({
|
||||
</div>
|
||||
)}
|
||||
|
||||
<DialogFooter className="gap-3">
|
||||
<DialogFooter>
|
||||
<Button
|
||||
type="button"
|
||||
variant="outline"
|
||||
|
||||
@@ -140,7 +140,7 @@ export function BulkActionDialog({
|
||||
</div>
|
||||
</RadioGroup>
|
||||
|
||||
<DialogFooter className="gap-2">
|
||||
<DialogFooter>
|
||||
<Button
|
||||
type="button"
|
||||
variant="outline"
|
||||
|
||||
@@ -185,9 +185,7 @@ export function LancamentoDetailsDialog({
|
||||
|
||||
<DialogFooter>
|
||||
<DialogClose asChild>
|
||||
<Button className="w-full" type="button">
|
||||
Entendi
|
||||
</Button>
|
||||
<Button type="button">Entendi</Button>
|
||||
</DialogClose>
|
||||
</DialogFooter>
|
||||
</CardContent>
|
||||
|
||||
@@ -504,9 +504,13 @@ const buildColumns = ({
|
||||
header: "Anotação",
|
||||
cell: ({ row }) => {
|
||||
const note = row.original.note;
|
||||
if (!note?.trim()) return <span className="text-muted-foreground">—</span>;
|
||||
if (!note?.trim())
|
||||
return <span className="text-muted-foreground">—</span>;
|
||||
return (
|
||||
<span className="max-w-[200px] truncate whitespace-pre-line text-sm" title={note}>
|
||||
<span
|
||||
className="max-w-[200px] truncate whitespace-pre-line text-sm"
|
||||
title={note}
|
||||
>
|
||||
{note}
|
||||
</span>
|
||||
);
|
||||
|
||||
@@ -88,7 +88,7 @@ export function BudgetDialog({
|
||||
setFormState(initialState);
|
||||
setErrorMessage(null);
|
||||
}
|
||||
}, [dialogOpen, setFormState, budget, defaultPeriod]);
|
||||
}, [dialogOpen, setFormState, initialState]);
|
||||
|
||||
// Clear error when dialog closes
|
||||
useEffect(() => {
|
||||
@@ -180,7 +180,7 @@ export function BudgetDialog({
|
||||
Cadastre pelo menos uma categoria de despesa para criar um
|
||||
orçamento.
|
||||
</div>
|
||||
<DialogFooter className="gap-3">
|
||||
<DialogFooter>
|
||||
<Button
|
||||
type="button"
|
||||
variant="outline"
|
||||
@@ -242,7 +242,7 @@ export function BudgetDialog({
|
||||
</p>
|
||||
) : null}
|
||||
|
||||
<DialogFooter className="gap-3">
|
||||
<DialogFooter>
|
||||
<Button
|
||||
type="button"
|
||||
variant="outline"
|
||||
|
||||
@@ -421,7 +421,7 @@ export function PagadorInfoCard({
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<DialogFooter className="gap-2">
|
||||
<DialogFooter>
|
||||
<Button
|
||||
type="button"
|
||||
variant="outline"
|
||||
|
||||
@@ -311,7 +311,7 @@ export function PagadorDialog({
|
||||
<p className="text-sm text-destructive">{errorMessage}</p>
|
||||
) : null}
|
||||
|
||||
<DialogFooter className="gap-3">
|
||||
<DialogFooter>
|
||||
<Button
|
||||
type="button"
|
||||
variant="outline"
|
||||
|
||||
@@ -112,9 +112,7 @@ export function InboxDetailsDialog({
|
||||
|
||||
<DialogFooter>
|
||||
<DialogClose asChild>
|
||||
<Button className="w-full mt-2" type="button">
|
||||
Entendi
|
||||
</Button>
|
||||
<Button type="button">Entendi</Button>
|
||||
</DialogClose>
|
||||
</DialogFooter>
|
||||
</DialogContent>
|
||||
|
||||
@@ -83,7 +83,7 @@ function AlertDialogFooter({
|
||||
<div
|
||||
data-slot="alert-dialog-footer"
|
||||
className={cn(
|
||||
"flex flex-col-reverse gap-2 sm:flex-row sm:justify-end",
|
||||
"flex flex-col-reverse gap-2 sm:flex-row [&>button]:flex-1",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
|
||||
@@ -36,10 +36,7 @@ function DialogOverlay({
|
||||
return (
|
||||
<DialogPrimitive.Overlay
|
||||
data-slot="dialog-overlay"
|
||||
className={cn(
|
||||
"fixed inset-0 z-50 bg-black/50",
|
||||
className,
|
||||
)}
|
||||
className={cn("fixed inset-0 z-50 bg-black/50", className)}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
@@ -59,7 +56,7 @@ function DialogContent({
|
||||
<DialogPrimitive.Content
|
||||
data-slot="dialog-content"
|
||||
className={cn(
|
||||
"bg-background fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border p-6 shadow-lg sm:max-w-lg",
|
||||
"bg-background fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border p-10 shadow-lg sm:max-w-xl",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
@@ -94,7 +91,7 @@ function DialogFooter({ className, ...props }: React.ComponentProps<"div">) {
|
||||
<div
|
||||
data-slot="dialog-footer"
|
||||
className={cn(
|
||||
"flex flex-col-reverse gap-2 sm:flex-row sm:justify-end",
|
||||
"flex flex-col-reverse gap-2 sm:flex-row [&>button]:flex-1",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
|
||||
@@ -107,10 +107,14 @@ export const preferenciasUsuario = pgTable("preferencias_usuario", {
|
||||
.unique()
|
||||
.references(() => user.id, { onDelete: "cascade" }),
|
||||
disableMagnetlines: boolean("disable_magnetlines").notNull().default(false),
|
||||
extratoNoteAsColumn: boolean("extrato_note_as_column").notNull().default(false),
|
||||
extratoNoteAsColumn: boolean("extrato_note_as_column")
|
||||
.notNull()
|
||||
.default(false),
|
||||
systemFont: text("system_font").notNull().default("ai-sans"),
|
||||
moneyFont: text("money_font").notNull().default("ai-sans"),
|
||||
lancamentosColumnOrder: jsonb("lancamentos_column_order").$type<string[] | null>(),
|
||||
lancamentosColumnOrder: jsonb("lancamentos_column_order").$type<
|
||||
string[] | null
|
||||
>(),
|
||||
dashboardWidgets: jsonb("dashboard_widgets").$type<{
|
||||
order: string[];
|
||||
hidden: string[];
|
||||
|
||||
@@ -56,7 +56,9 @@ export function parseChangelog(): ChangelogVersion[] {
|
||||
}
|
||||
|
||||
// **Contribuições:** ou **Autor:** com texto/link opcional
|
||||
const contributorMatch = line.match(/^\*\*(?:Contribuições|Autor):\*\*\s*(.+)$/);
|
||||
const contributorMatch = line.match(
|
||||
/^\*\*(?:Contribuições|Autor):\*\*\s*(.+)$/,
|
||||
);
|
||||
if (contributorMatch && currentVersion) {
|
||||
currentVersion.contributor = contributorMatch[1].trim() || undefined;
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { inArray } from "drizzle-orm";
|
||||
import { Resend } from "resend";
|
||||
import { pagadores } from "@/db/schema";
|
||||
import { getResendFromEmail } from "@/lib/email/resend";
|
||||
import { db } from "@/lib/db";
|
||||
import { getResendFromEmail } from "@/lib/email/resend";
|
||||
|
||||
type ActionType = "created" | "deleted";
|
||||
|
||||
|
||||
Reference in New Issue
Block a user