diff --git a/src/components/credito/CartaoSelectField.tsx b/src/components/credito/CartaoSelectField.tsx new file mode 100644 index 0000000..f2831c4 --- /dev/null +++ b/src/components/credito/CartaoSelectField.tsx @@ -0,0 +1,37 @@ + +import { FormControl, FormItem, FormLabel, FormMessage } from "@/components/ui/form"; +import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"; +import { CartaoCredito } from "@/types/cartaoTypes"; + +interface CartaoSelectFieldProps { + cartoes: CartaoCredito[]; + value: string; + onChange: (value: string) => void; + formatCartaoLabel: (cartao: CartaoCredito) => string; +} + +export function CartaoSelectField({ cartoes, value, onChange, formatCartaoLabel }: CartaoSelectFieldProps) { + return ( + + Cartão de Crédito + + + + ); +} diff --git a/src/components/credito/DatePickerField.tsx b/src/components/credito/DatePickerField.tsx new file mode 100644 index 0000000..517e9ec --- /dev/null +++ b/src/components/credito/DatePickerField.tsx @@ -0,0 +1,57 @@ + +import { CalendarIcon } from "lucide-react"; +import { format } from "date-fns"; +import { ptBR } from "date-fns/locale"; +import { FormControl, FormItem, FormLabel, FormMessage } from "@/components/ui/form"; +import { Button } from "@/components/ui/button"; +import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover"; +import { Calendar } from "@/components/ui/calendar"; +import { cn } from "@/lib/utils"; + +interface DatePickerFieldProps { + value: Date; + onChange: (date: Date | undefined) => void; + label: string; +} + +export function DatePickerField({ value, onChange, label }: DatePickerFieldProps) { + return ( + + {label} + + + + + + + + + date > new Date() || date < new Date("1900-01-01") + } + initialFocus + locale={ptBR} + className="p-3 pointer-events-auto" + /> + + + + + ); +} diff --git a/src/components/credito/DespesaCartaoFormSelect.tsx b/src/components/credito/DespesaCartaoFormSelect.tsx index ecc0905..4acd81a 100644 --- a/src/components/credito/DespesaCartaoFormSelect.tsx +++ b/src/components/credito/DespesaCartaoFormSelect.tsx @@ -1,49 +1,11 @@ -import { useState } from 'react'; -import { useForm } from 'react-hook-form'; -import { zodResolver } from '@hookform/resolvers/zod'; -import * as z from 'zod'; -import { useToast } from '@/components/ui/use-toast'; -import { CartaoCredito } from '@/types/cartaoTypes'; -import { criarDespesa } from '@/services/cartao/despesasService'; -import { CalendarIcon } from 'lucide-react'; -import { format } from 'date-fns'; -import { ptBR } from 'date-fns/locale'; -import { - Form, - FormControl, - FormField, - FormItem, - FormLabel, - FormMessage -} from '@/components/ui/form'; +import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from '@/components/ui/form'; import { Input } from '@/components/ui/input'; import { Button } from '@/components/ui/button'; -import { - Select, - SelectContent, - SelectItem, - SelectTrigger, - SelectValue, -} from "@/components/ui/select"; -import { - Popover, - PopoverContent, - PopoverTrigger, -} from "@/components/ui/popover"; -import { Calendar } from "@/components/ui/calendar"; -import { cn } from '@/lib/utils'; - -const despesaCartaoSchema = z.object({ - cartao_id: z.string().min(1, { message: 'Selecione um cartão' }), - valor: z.number().positive({ message: 'O valor deve ser maior que zero' }), - data_despesa: z.date({ - required_error: "Selecione uma data", - }), - descricao: z.string().min(1, { message: 'Descrição é obrigatória' }), -}); - -type DespesaCartaoFormValues = z.infer; +import { CartaoCredito } from '@/types/cartaoTypes'; +import { DespesaCartaoFormValues, useDespesaCartaoForm } from '@/hooks/useDespesaCartaoForm'; +import { CartaoSelectField } from './CartaoSelectField'; +import { DatePickerField } from './DatePickerField'; interface DespesaCartaoFormSelectProps { cartoes: CartaoCredito[]; @@ -52,90 +14,13 @@ interface DespesaCartaoFormSelectProps { } export function DespesaCartaoFormSelect({ cartoes, onSuccess, onCancel }: DespesaCartaoFormSelectProps) { - const [isSubmitting, setIsSubmitting] = useState(false); - const { toast } = useToast(); - const [selectedCartao, setSelectedCartao] = useState(null); - - const form = useForm({ - resolver: zodResolver(despesaCartaoSchema), - defaultValues: { - valor: undefined, - data_despesa: new Date(), - descricao: '', - } - }); - - const handleCartaoChange = (cartaoId: string) => { - const cartao = cartoes.find(c => c.id === cartaoId); - setSelectedCartao(cartao || null); - }; - - const formatCartaoLabel = (cartao: CartaoCredito) => { - let label = cartao.nome; - if (cartao.banco) label += ` - ${cartao.banco}`; - if (cartao.bandeira) label += ` (${cartao.bandeira})`; - return label; - }; - - async function onSubmit(data: DespesaCartaoFormValues) { - if (!selectedCartao) { - toast({ - title: "Erro", - description: "Selecione um cartão primeiro", - variant: "destructive" - }); - return; - } - - setIsSubmitting(true); - - try { - const formattedDate = format(data.data_despesa, 'yyyy-MM-dd'); - - // Garantir que temos um cartao_codigo, mesmo que seja gerado na hora - const cartaoCodigo = selectedCartao.cartao_codigo || selectedCartao.nome; - - console.log('Enviando dados para criar despesa:', { - cartao_id: data.cartao_id, - cartao_nome: selectedCartao.nome, - cartao_codigo: cartaoCodigo, - valor: data.valor, - data_despesa: formattedDate, - descricao: data.descricao - }); - - const resultado = await criarDespesa( - data.cartao_id, - cartaoCodigo, - data.valor, - formattedDate, - data.descricao - ); - - if (resultado) { - toast({ - title: "Despesa adicionada", - description: "Despesa do cartão registrada com sucesso", - }); - onSuccess(); - } else { - toast({ - title: "Erro ao salvar", - description: "Não foi possível salvar a despesa do cartão", - variant: "destructive" - }); - } - } catch (error) { - console.error('Erro ao processar formulário:', error); - toast({ - title: "Erro inesperado", - description: "Ocorreu um erro ao processar sua solicitação", - variant: "destructive" - }); - } finally { - setIsSubmitting(false); - } - } + const { + form, + isSubmitting, + handleCartaoChange, + formatCartaoLabel, + onSubmit + } = useDespesaCartaoForm({ cartoes, onSuccess, onCancel }); return (
@@ -144,30 +29,15 @@ export function DespesaCartaoFormSelect({ cartoes, onSuccess, onCancel }: Despes control={form.control} name="cartao_id" render={({ field }) => ( - - Cartão de Crédito - - - + { + field.onChange(value); + handleCartaoChange(value); + }} + formatCartaoLabel={formatCartaoLabel} + /> )} /> @@ -195,42 +65,11 @@ export function DespesaCartaoFormSelect({ cartoes, onSuccess, onCancel }: Despes control={form.control} name="data_despesa" render={({ field }) => ( - - Data da Despesa - - - - - - - - - date > new Date() || date < new Date("1900-01-01") - } - initialFocus - locale={ptBR} - /> - - - - + )} /> diff --git a/src/hooks/useDespesaCartaoForm.ts b/src/hooks/useDespesaCartaoForm.ts new file mode 100644 index 0000000..2a40721 --- /dev/null +++ b/src/hooks/useDespesaCartaoForm.ts @@ -0,0 +1,122 @@ + +import { useState } from 'react'; +import { useForm } from 'react-hook-form'; +import { zodResolver } from '@hookform/resolvers/zod'; +import * as z from 'zod'; +import { useToast } from '@/hooks/use-toast'; +import { CartaoCredito } from '@/types/cartaoTypes'; +import { criarDespesa } from '@/services/cartao/despesasService'; +import { format } from 'date-fns'; + +const despesaCartaoSchema = z.object({ + cartao_id: z.string().min(1, { message: 'Selecione um cartão' }), + valor: z.number().positive({ message: 'O valor deve ser maior que zero' }), + data_despesa: z.date({ + required_error: "Selecione uma data", + }), + descricao: z.string().min(1, { message: 'Descrição é obrigatória' }), +}); + +export type DespesaCartaoFormValues = z.infer; + +interface UseDespesaCartaoFormProps { + cartoes: CartaoCredito[]; + onSuccess: () => void; + onCancel: () => void; +} + +export function useDespesaCartaoForm({ cartoes, onSuccess, onCancel }: UseDespesaCartaoFormProps) { + const [isSubmitting, setIsSubmitting] = useState(false); + const { toast } = useToast(); + const [selectedCartao, setSelectedCartao] = useState(null); + + const form = useForm({ + resolver: zodResolver(despesaCartaoSchema), + defaultValues: { + valor: undefined, + data_despesa: new Date(), + descricao: '', + } + }); + + const handleCartaoChange = (cartaoId: string) => { + const cartao = cartoes.find(c => c.id === cartaoId); + setSelectedCartao(cartao || null); + }; + + const formatCartaoLabel = (cartao: CartaoCredito) => { + let label = cartao.nome; + if (cartao.banco) label += ` - ${cartao.banco}`; + if (cartao.bandeira) label += ` (${cartao.bandeira})`; + return label; + }; + + async function onSubmit(data: DespesaCartaoFormValues) { + if (!selectedCartao) { + toast({ + title: "Erro", + description: "Selecione um cartão primeiro", + variant: "destructive" + }); + return; + } + + setIsSubmitting(true); + + try { + const formattedDate = format(data.data_despesa, 'yyyy-MM-dd'); + + // Garantir que temos um cartao_codigo, mesmo que seja gerado na hora + const cartaoCodigo = selectedCartao.cartao_codigo || selectedCartao.nome; + + console.log('Enviando dados para criar despesa:', { + cartao_id: data.cartao_id, + cartao_nome: selectedCartao.nome, + cartao_codigo: cartaoCodigo, + valor: data.valor, + data_despesa: formattedDate, + descricao: data.descricao + }); + + const resultado = await criarDespesa( + data.cartao_id, + cartaoCodigo, + data.valor, + formattedDate, + data.descricao + ); + + if (resultado) { + toast({ + title: "Despesa adicionada", + description: "Despesa do cartão registrada com sucesso", + }); + onSuccess(); + } else { + toast({ + title: "Erro ao salvar", + description: "Não foi possível salvar a despesa do cartão", + variant: "destructive" + }); + } + } catch (error) { + console.error('Erro ao processar formulário:', error); + toast({ + title: "Erro inesperado", + description: "Ocorreu um erro ao processar sua solicitação", + variant: "destructive" + }); + } finally { + setIsSubmitting(false); + } + } + + return { + form, + isSubmitting, + selectedCartao, + handleCartaoChange, + formatCartaoLabel, + onSubmit + }; +}