Skip to content

Commit

Permalink
feat: ✨ add transaction button component
Browse files Browse the repository at this point in the history
  • Loading branch information
neopromic committed Nov 9, 2024
1 parent ede8a12 commit 2327e31
Showing 1 changed file with 252 additions and 0 deletions.
252 changes: 252 additions & 0 deletions app/_components/add-transaction-button.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,252 @@
"use client";

import {
Dialog,
DialogClose,
DialogContent,
DialogDescription,
DialogFooter,
DialogHeader,
DialogTitle,
} from "@/app/_components/ui/dialog";
import { Button } from "./ui/button";
import { ArrowDownUp } from "lucide-react";
import { DialogTrigger } from "./ui/dialog";
import { z } from "zod";
import {
TransactionCategory,
TransactionPaymentMethod,
TransactionType,
} from "@prisma/client";
import { zodResolver } from "@hookform/resolvers/zod";
import { useForm } from "react-hook-form";
import {
Form,
FormField,
FormItem,
FormLabel,
FormControl,
FormMessage,
} from "./ui/form";
import { Input } from "./ui/input";
import { MoneyInput } from "./money-input";
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from "./ui/select";
import {
TRANSACTION_CATEGORY_MAP,
TRANSACTION_PAYMENT_METHOD_MAP,
transactionTypeOptions,
} from "../_constants/transaction";
import { DatePicker } from "./ui/date-picker";

const formSchema = z.object({
name: z.string().trim().min(1, { message: "O nome é obrigatório" }),
amount: z.string().trim().min(1, { message: "O valor é obrigatório" }),
type: z.nativeEnum(TransactionType, {
required_error: "O tipo é obrigatório",
}),
category: z.nativeEnum(TransactionCategory, {
required_error: "A categoria é obrigatória",
}),
paymentMethod: z.nativeEnum(TransactionPaymentMethod, {
required_error: "O método de pagamento é obrigatório",
}),
date: z.date({
required_error: "A data é obrigatória",
}),
});

type FormData = z.infer<typeof formSchema>;

const AddTransactionButton = () => {
const form = useForm<FormData>({
resolver: zodResolver(formSchema),
defaultValues: {
amount: "",
category: TransactionCategory.OTHER,
name: "",
paymentMethod: TransactionPaymentMethod.CASH,
date: new Date(),
type: TransactionType.EXPENSE,
},
});

const onSubmit = (data: FormData) => {
console.log({ data });
};

return (
<Dialog>
<DialogTrigger asChild>
<Button className="rounded-full">
Adicionar transação
<ArrowDownUp className="h-4 w-4" />
</Button>
</DialogTrigger>
<DialogContent className="max-h-[90vh] overflow-y-auto">
<DialogHeader>
<DialogTitle>Adicionar transação</DialogTitle>
<DialogDescription>
Adicione uma nova transação para começar a gerenciar suas finanças.
Insira as informações abaixo para continuar.
</DialogDescription>
</DialogHeader>
<Form {...form}>
<form
onSubmit={form.handleSubmit(onSubmit)}
className="space-y-6 py-4"
>
<FormField
control={form.control}
name="name"
render={({ field }) => (
<FormItem>
<FormLabel>Título</FormLabel>
<FormControl>
<Input placeholder="Nome da transação" {...field} />
</FormControl>

<FormMessage />
</FormItem>
)}
/>

<FormField
control={form.control}
name="amount"
render={({ field }) => (
<FormItem>
<FormLabel>Valor da transação</FormLabel>
<FormControl>
<MoneyInput {...field} />
</FormControl>

<FormMessage />
</FormItem>
)}
/>

<FormField
control={form.control}
name="type"
render={({ field }) => (
<FormItem>
<FormLabel>Tipo da transação</FormLabel>
<Select
onValueChange={field.onChange}
defaultValue={field.value}
>
<FormControl>
<SelectTrigger>
<SelectValue placeholder="Selecione o tipo" />
</SelectTrigger>
</FormControl>
<SelectContent>
{transactionTypeOptions.map((option) => (
<SelectItem key={option.value} value={option.value}>
{option.label}
</SelectItem>
))}
</SelectContent>
</Select>

<FormMessage />
</FormItem>
)}
/>

<FormField
control={form.control}
name="category"
render={({ field }) => (
<FormItem>
<FormLabel>Categoria</FormLabel>
<Select
onValueChange={field.onChange}
defaultValue={field.value}
>
<FormControl>
<SelectTrigger>
<SelectValue placeholder="Selecione a categoria" />
</SelectTrigger>
</FormControl>
<SelectContent>
{Object.entries(TRANSACTION_CATEGORY_MAP).map(
([key, label]) => (
<SelectItem key={key} value={key}>
{label}
</SelectItem>
),
)}
</SelectContent>
</Select>

<FormMessage />
</FormItem>
)}
/>

<FormField
control={form.control}
name="paymentMethod"
render={({ field }) => (
<FormItem>
<FormLabel>Método de pagamento</FormLabel>
<Select
onValueChange={field.onChange}
defaultValue={field.value}
>
<FormControl>
<SelectTrigger>
<SelectValue placeholder="Selecione o método de pagamento" />
</SelectTrigger>
</FormControl>
<SelectContent>
{Object.entries(TRANSACTION_PAYMENT_METHOD_MAP).map(
([key, label]) => (
<SelectItem key={key} value={key}>
{label}
</SelectItem>
),
)}
</SelectContent>
</Select>

<FormMessage />
</FormItem>
)}
/>

<FormField
control={form.control}
name="date"
render={({ field }) => (
<FormItem>
<FormLabel>Data</FormLabel>
<DatePicker value={field.value} onChange={field.onChange} />
<FormMessage />
</FormItem>
)}
/>

<DialogFooter>
<DialogClose asChild>
<Button variant="outline" type="button">
Cancelar
</Button>
</DialogClose>
<Button type="submit">Adicionar</Button>
</DialogFooter>
</form>
</Form>
</DialogContent>
</Dialog>
);
};

export default AddTransactionButton;

0 comments on commit 2327e31

Please sign in to comment.