From 570aa713b1b2becf7c06c89610c75d2cb119b532 Mon Sep 17 00:00:00 2001 From: Sebastien Castiel Date: Wed, 6 Dec 2023 15:08:52 -0500 Subject: Delete expense --- .../[groupId]/expenses/[expenseId]/edit/page.tsx | 9 ++++- src/components/async-button.tsx | 42 ++++++++++++++++++++++ src/components/expense-form.tsx | 27 +++++++++++--- src/components/group-form.tsx | 7 ++-- src/components/submit-button.tsx | 12 +++---- src/lib/api.ts | 8 +++++ 6 files changed, 91 insertions(+), 14 deletions(-) create mode 100644 src/components/async-button.tsx (limited to 'src') diff --git a/src/app/groups/[groupId]/expenses/[expenseId]/edit/page.tsx b/src/app/groups/[groupId]/expenses/[expenseId]/edit/page.tsx index 934d346..0623f50 100644 --- a/src/app/groups/[groupId]/expenses/[expenseId]/edit/page.tsx +++ b/src/app/groups/[groupId]/expenses/[expenseId]/edit/page.tsx @@ -1,5 +1,5 @@ import { ExpenseForm } from '@/components/expense-form' -import { getExpense, getGroup, updateExpense } from '@/lib/api' +import { deleteExpense, getExpense, getGroup, updateExpense } from '@/lib/api' import { expenseFormSchema } from '@/lib/schemas' import { notFound, redirect } from 'next/navigation' @@ -20,11 +20,18 @@ export default async function EditExpensePage({ redirect(`/groups/${groupId}`) } + async function deleteExpenseAction() { + 'use server' + await deleteExpense(expenseId) + redirect(`/groups/${groupId}`) + } + return ( ) } diff --git a/src/components/async-button.tsx b/src/components/async-button.tsx new file mode 100644 index 0000000..7d2bf93 --- /dev/null +++ b/src/components/async-button.tsx @@ -0,0 +1,42 @@ +'use client' +import { Button, ButtonProps } from '@/components/ui/button' +import { Loader2 } from 'lucide-react' +import { ReactNode, useState } from 'react' + +type Props = ButtonProps & { + action?: () => Promise + loadingContent?: ReactNode +} + +export function AsyncButton({ + action, + children, + loadingContent, + ...props +}: Props) { + const [loading, setLoading] = useState(false) + return ( + + ) +} diff --git a/src/components/expense-form.tsx b/src/components/expense-form.tsx index 35c6aaf..3202788 100644 --- a/src/components/expense-form.tsx +++ b/src/components/expense-form.tsx @@ -1,4 +1,5 @@ 'use client' +import { AsyncButton } from '@/components/async-button' import { SubmitButton } from '@/components/submit-button' import { Card, @@ -33,10 +34,12 @@ import { useForm } from 'react-hook-form' export type Props = { group: NonNullable>> expense?: NonNullable>> - onSubmit: (values: ExpenseFormValues) => void + onSubmit: (values: ExpenseFormValues) => Promise + onDelete?: () => Promise } -export function ExpenseForm({ group, expense, onSubmit }: Props) { +export function ExpenseForm({ group, expense, onSubmit, onDelete }: Props) { + const isCreate = expense === undefined const form = useForm({ resolver: zodResolver(expenseFormSchema), defaultValues: expense @@ -54,7 +57,9 @@ export function ExpenseForm({ group, expense, onSubmit }: Props) {
onSubmit(values))}> - Expense information + + {isCreate ? <>Create expense : <>Edit expense} + - - Submit + + + {isCreate ? <>Create : <>Save} + + {!isCreate && onDelete && ( + + Delete + + )}
diff --git a/src/components/group-form.tsx b/src/components/group-form.tsx index 5ddc865..2e21aea 100644 --- a/src/components/group-form.tsx +++ b/src/components/group-form.tsx @@ -22,6 +22,7 @@ import { Input } from '@/components/ui/input' import { getGroup } from '@/lib/api' import { GroupFormValues, groupFormSchema } from '@/lib/schemas' import { zodResolver } from '@hookform/resolvers/zod' +import { Trash2 } from 'lucide-react' import { useFieldArray, useForm } from 'react-hook-form' export type Props = { @@ -105,11 +106,13 @@ export function GroupForm({ group, onSubmit }: Props) {
diff --git a/src/components/submit-button.tsx b/src/components/submit-button.tsx index 7489c6c..c5215c5 100644 --- a/src/components/submit-button.tsx +++ b/src/components/submit-button.tsx @@ -1,16 +1,16 @@ -import { Button } from '@/components/ui/button' +import { Button, ButtonProps } from '@/components/ui/button' import { Loader2 } from 'lucide-react' -import { PropsWithChildren, ReactNode } from 'react' +import { ReactNode } from 'react' import { useFormState } from 'react-hook-form' -type Props = PropsWithChildren<{ +type Props = { loadingContent: ReactNode -}> +} & ButtonProps -export function SubmitButton({ children, loadingContent }: Props) { +export function SubmitButton({ children, loadingContent, ...props }: Props) { const { isSubmitting } = useFormState() return ( -