refactor(contas): melhorar modal de transferência entre contas

- Usar DatePicker e PeriodPicker consistentes com modal de lançamentos
- Adicionar logos das contas nos selects de origem e destino
- Usar ContaCartaoSelectContent para exibição padronizada

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Felipe Coutinho
2026-01-20 13:52:04 +00:00
parent 5b8f8fc42b
commit b871e68437

View File

@@ -2,8 +2,11 @@
import { transferBetweenAccountsAction } from "@/app/(dashboard)/contas/actions"; import { transferBetweenAccountsAction } from "@/app/(dashboard)/contas/actions";
import type { AccountData } from "@/app/(dashboard)/contas/data"; import type { AccountData } from "@/app/(dashboard)/contas/data";
import { ContaCartaoSelectContent } from "@/components/lancamentos/select-items";
import { PeriodPicker } from "@/components/period-picker";
import { Button } from "@/components/ui/button"; import { Button } from "@/components/ui/button";
import { CurrencyInput } from "@/components/ui/currency-input"; import { CurrencyInput } from "@/components/ui/currency-input";
import { DatePicker } from "@/components/ui/date-picker";
import { import {
Dialog, Dialog,
DialogContent, DialogContent,
@@ -13,7 +16,6 @@ import {
DialogTitle, DialogTitle,
DialogTrigger, DialogTrigger,
} from "@/components/ui/dialog"; } from "@/components/ui/dialog";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label"; import { Label } from "@/components/ui/label";
import { import {
Select, Select,
@@ -23,7 +25,7 @@ import {
SelectValue, SelectValue,
} from "@/components/ui/select"; } from "@/components/ui/select";
import { useControlledState } from "@/hooks/use-controlled-state"; import { useControlledState } from "@/hooks/use-controlled-state";
import { formatDateForDb } from "@/lib/utils/date"; import { getTodayDateString } from "@/lib/utils/date";
import { useMemo, useState, useTransition } from "react"; import { useMemo, useState, useTransition } from "react";
import { toast } from "sonner"; import { toast } from "sonner";
@@ -56,7 +58,7 @@ export function TransferDialog({
// Form state // Form state
const [toAccountId, setToAccountId] = useState(""); const [toAccountId, setToAccountId] = useState("");
const [amount, setAmount] = useState(""); const [amount, setAmount] = useState("");
const [date, setDate] = useState(formatDateForDb(new Date())); const [date, setDate] = useState(getTodayDateString());
const [period, setPeriod] = useState(currentPeriod); const [period, setPeriod] = useState(currentPeriod);
// Available destination accounts (exclude source account) // Available destination accounts (exclude source account)
@@ -105,7 +107,7 @@ export function TransferDialog({
// Reset form // Reset form
setToAccountId(""); setToAccountId("");
setAmount(""); setAmount("");
setDate(formatDateForDb(new Date())); setDate(getTodayDateString());
setPeriod(currentPeriod); setPeriod(currentPeriod);
return; return;
} }
@@ -130,24 +132,20 @@ export function TransferDialog({
<div className="grid grid-cols-1 gap-4 sm:grid-cols-2"> <div className="grid grid-cols-1 gap-4 sm:grid-cols-2">
<div className="flex flex-col gap-2"> <div className="flex flex-col gap-2">
<Label htmlFor="transfer-date">Data da transferência</Label> <Label htmlFor="transfer-date">Data da transferência</Label>
<Input <DatePicker
id="transfer-date" id="transfer-date"
type="date"
value={date} value={date}
onChange={(e) => setDate(e.target.value)} onChange={setDate}
required required
/> />
</div> </div>
<div className="flex flex-col gap-2"> <div className="flex flex-col gap-2">
<Label htmlFor="transfer-period">Período</Label> <Label htmlFor="transfer-period">Período</Label>
<Input <PeriodPicker
id="transfer-period"
type="month"
value={period} value={period}
onChange={(e) => setPeriod(e.target.value)} onChange={setPeriod}
placeholder="AAAA-MM" className="w-full"
required
/> />
</div> </div>
@@ -164,12 +162,30 @@ export function TransferDialog({
<div className="flex flex-col gap-2 sm:col-span-2"> <div className="flex flex-col gap-2 sm:col-span-2">
<Label htmlFor="from-account">Conta de origem</Label> <Label htmlFor="from-account">Conta de origem</Label>
<Input <Select value={fromAccountId} disabled>
id="from-account" <SelectTrigger id="from-account" className="w-full">
value={fromAccount?.name || ""} <SelectValue>
disabled {fromAccount && (
className="bg-muted" <ContaCartaoSelectContent
/> label={fromAccount.name}
logo={fromAccount.logo}
isCartao={false}
/>
)}
</SelectValue>
</SelectTrigger>
<SelectContent>
{fromAccount && (
<SelectItem value={fromAccount.id}>
<ContaCartaoSelectContent
label={fromAccount.name}
logo={fromAccount.logo}
isCartao={false}
/>
</SelectItem>
)}
</SelectContent>
</Select>
</div> </div>
<div className="flex flex-col gap-2 sm:col-span-2"> <div className="flex flex-col gap-2 sm:col-span-2">
@@ -182,12 +198,30 @@ export function TransferDialog({
) : ( ) : (
<Select value={toAccountId} onValueChange={setToAccountId}> <Select value={toAccountId} onValueChange={setToAccountId}>
<SelectTrigger id="to-account" className="w-full"> <SelectTrigger id="to-account" className="w-full">
<SelectValue placeholder="Selecione a conta de destino" /> <SelectValue placeholder="Selecione a conta de destino">
{toAccountId &&
(() => {
const selectedAccount = availableAccounts.find(
(acc) => acc.id === toAccountId,
);
return selectedAccount ? (
<ContaCartaoSelectContent
label={selectedAccount.name}
logo={selectedAccount.logo}
isCartao={false}
/>
) : null;
})()}
</SelectValue>
</SelectTrigger> </SelectTrigger>
<SelectContent className="w-full"> <SelectContent className="w-full">
{availableAccounts.map((account) => ( {availableAccounts.map((account) => (
<SelectItem key={account.id} value={account.id}> <SelectItem key={account.id} value={account.id}>
{account.name} - {account.accountType} <ContaCartaoSelectContent
label={account.name}
logo={account.logo}
isCartao={false}
/>
</SelectItem> </SelectItem>
))} ))}
</SelectContent> </SelectContent>