aboutsummaryrefslogtreecommitdiffstats
path: root/src/app
diff options
context:
space:
mode:
authorSebastien Castiel <sebastien@castiel.me>2023-12-19 09:44:09 -0500
committerSebastien Castiel <sebastien@castiel.me>2023-12-19 09:44:09 -0500
commitf881aff5f9993c3a6b4b0d8ed7e67d2f812f39d6 (patch)
tree685731e70ad838dbc2b3d70450e090e1e5fc31c9 /src/app
parent1e66efe5169dfad9a0c62ba42fbf31ce977bf49e (diff)
Revert "Use modal dialogs for expense creation & edition (#10)"
This reverts commit 1e66efe5169dfad9a0c62ba42fbf31ce977bf49e.
Diffstat (limited to 'src/app')
-rw-r--r--src/app/groups/[groupId]/@modal/default.tsx3
-rw-r--r--src/app/groups/[groupId]/@modal/expense-modal.tsx83
-rw-r--r--src/app/groups/[groupId]/@modal/expenses/[expenseId]/edit/page.tsx26
-rw-r--r--src/app/groups/[groupId]/@modal/expenses/create/page.tsx24
-rw-r--r--src/app/groups/[groupId]/expenses/[expenseId]/edit/page.tsx42
-rw-r--r--src/app/groups/[groupId]/expenses/actions.ts28
-rw-r--r--src/app/groups/[groupId]/expenses/create/page.tsx27
-rw-r--r--src/app/groups/[groupId]/expenses/expense-list.tsx9
-rw-r--r--src/app/groups/[groupId]/expenses/expense-page.tsx19
-rw-r--r--src/app/groups/[groupId]/expenses/layout.tsx9
-rw-r--r--src/app/groups/[groupId]/expenses/page.tsx2
-rw-r--r--src/app/groups/[groupId]/layout.tsx5
-rw-r--r--src/app/groups/[groupId]/not-found.tsx5
-rw-r--r--src/app/groups/[groupId]/reimbursement-list.tsx1
14 files changed, 73 insertions, 210 deletions
diff --git a/src/app/groups/[groupId]/@modal/default.tsx b/src/app/groups/[groupId]/@modal/default.tsx
deleted file mode 100644
index 86b9e9a..0000000
--- a/src/app/groups/[groupId]/@modal/default.tsx
+++ /dev/null
@@ -1,3 +0,0 @@
-export default function Default() {
- return null
-}
diff --git a/src/app/groups/[groupId]/@modal/expense-modal.tsx b/src/app/groups/[groupId]/@modal/expense-modal.tsx
deleted file mode 100644
index 17bb302..0000000
--- a/src/app/groups/[groupId]/@modal/expense-modal.tsx
+++ /dev/null
@@ -1,83 +0,0 @@
-'use client'
-import {
- Dialog,
- DialogContent,
- DialogHeader,
- DialogTitle,
-} from '@/components/ui/dialog'
-import { useRouter } from 'next/navigation'
-import { ReactNode, useEffect, useState } from 'react'
-import { Drawer } from 'vaul'
-
-type Props = {
- children: ReactNode
- title: ReactNode
-}
-
-export function ExpenseModal(props: Props) {
- const size = useTailwindBreakpoint()
- if (size === 'xs') {
- return <ExpenseVaul {...props} />
- } else {
- return <ExpenseDialog {...props} />
- }
-}
-
-export function ExpenseDialog({ children, title }: Props) {
- const router = useRouter()
-
- return (
- <Dialog open onOpenChange={() => router.back()}>
- <DialogContent className="w-full max-w-screen-sm">
- <DialogHeader>
- <DialogTitle>{title}</DialogTitle>
- </DialogHeader>
- {children}
- </DialogContent>
- </Dialog>
- )
-}
-
-export function ExpenseVaul({ children, title }: Props) {
- const router = useRouter()
- return (
- <Drawer.Root open onClose={() => router.back()}>
- <Drawer.Portal>
- <Drawer.Title>{title}</Drawer.Title>
- <Drawer.Overlay className="fixed inset-0 bg-background/80 backdrop-blur-sm" />
- <Drawer.Content className="bg-background border flex flex-col rounded-t-[10px] max-h-[90dvh] mt-24 fixed bottom-0 left-0 right-0 z-50">
- <div className="mx-auto w-12 h-1.5 flex-shrink-0 rounded-full bg-gray-300 dark:bg-gray-700 mt-4"></div>
- <div className="text-xl font-bold p-4">{title}</div>
- <div className="flex-1 overflow-y-auto p-4 pt-0">{children}</div>
- </Drawer.Content>
- </Drawer.Portal>
- </Drawer.Root>
- )
-}
-
-export function useTailwindBreakpoint() {
- const [size, setSize] = useState<'xs' | 'sm' | 'md' | 'lg'>('xs')
-
- useEffect(() => {
- const handleBreakpointChange = () => {
- if (window.innerWidth >= 1200) {
- setSize('lg')
- } else if (window.innerWidth >= 768) {
- setSize('md')
- } else if (window.innerWidth >= 640) {
- setSize('sm')
- } else {
- setSize('xs')
- }
- }
-
- window.addEventListener('resize', handleBreakpointChange)
- handleBreakpointChange()
-
- return () => {
- window.removeEventListener('resize', handleBreakpointChange)
- }
- }, [])
-
- return size
-}
diff --git a/src/app/groups/[groupId]/@modal/expenses/[expenseId]/edit/page.tsx b/src/app/groups/[groupId]/@modal/expenses/[expenseId]/edit/page.tsx
deleted file mode 100644
index fb70f45..0000000
--- a/src/app/groups/[groupId]/@modal/expenses/[expenseId]/edit/page.tsx
+++ /dev/null
@@ -1,26 +0,0 @@
-import { ExpenseModal } from '@/app/groups/[groupId]/@modal/expense-modal'
-import { ExpenseForm } from '@/components/expense-form'
-import { getExpense, getGroup } from '@/lib/api'
-import { Metadata } from 'next'
-import { notFound } from 'next/navigation'
-
-export const metadata: Metadata = {
- title: 'Edit expense',
-}
-
-export default async function EditExpensePage({
- params: { groupId, expenseId },
-}: {
- params: { groupId: string; expenseId: string }
-}) {
- const group = await getGroup(groupId)
- if (!group) notFound()
- const expense = await getExpense(groupId, expenseId)
- if (!expense) notFound()
-
- return (
- <ExpenseModal title="Edit expense">
- <ExpenseForm group={group} expense={expense} />
- </ExpenseModal>
- )
-}
diff --git a/src/app/groups/[groupId]/@modal/expenses/create/page.tsx b/src/app/groups/[groupId]/@modal/expenses/create/page.tsx
deleted file mode 100644
index 93cc413..0000000
--- a/src/app/groups/[groupId]/@modal/expenses/create/page.tsx
+++ /dev/null
@@ -1,24 +0,0 @@
-import { ExpenseModal } from '@/app/groups/[groupId]/@modal/expense-modal'
-import { ExpenseForm } from '@/components/expense-form'
-import { getGroup } from '@/lib/api'
-import { Metadata } from 'next'
-import { notFound } from 'next/navigation'
-
-export const metadata: Metadata = {
- title: 'Create expense',
-}
-
-export default async function ExpensePage({
- params: { groupId },
-}: {
- params: { groupId: string }
-}) {
- const group = await getGroup(groupId)
- if (!group) notFound()
-
- return (
- <ExpenseModal title="Create expense">
- <ExpenseForm group={group} />
- </ExpenseModal>
- )
-}
diff --git a/src/app/groups/[groupId]/expenses/[expenseId]/edit/page.tsx b/src/app/groups/[groupId]/expenses/[expenseId]/edit/page.tsx
new file mode 100644
index 0000000..188d08f
--- /dev/null
+++ b/src/app/groups/[groupId]/expenses/[expenseId]/edit/page.tsx
@@ -0,0 +1,42 @@
+import { ExpenseForm } from '@/components/expense-form'
+import { deleteExpense, getExpense, getGroup, updateExpense } from '@/lib/api'
+import { expenseFormSchema } from '@/lib/schemas'
+import { Metadata } from 'next'
+import { notFound, redirect } from 'next/navigation'
+
+export const metadata: Metadata = {
+ title: 'Edit expense',
+}
+
+export default async function EditExpensePage({
+ params: { groupId, expenseId },
+}: {
+ params: { groupId: string; expenseId: string }
+}) {
+ const group = await getGroup(groupId)
+ if (!group) notFound()
+ const expense = await getExpense(groupId, expenseId)
+ if (!expense) notFound()
+
+ async function updateExpenseAction(values: unknown) {
+ 'use server'
+ const expenseFormValues = expenseFormSchema.parse(values)
+ await updateExpense(groupId, expenseId, expenseFormValues)
+ redirect(`/groups/${groupId}`)
+ }
+
+ async function deleteExpenseAction() {
+ 'use server'
+ await deleteExpense(expenseId)
+ redirect(`/groups/${groupId}`)
+ }
+
+ return (
+ <ExpenseForm
+ group={group}
+ expense={expense}
+ onSubmit={updateExpenseAction}
+ onDelete={deleteExpenseAction}
+ />
+ )
+}
diff --git a/src/app/groups/[groupId]/expenses/actions.ts b/src/app/groups/[groupId]/expenses/actions.ts
deleted file mode 100644
index 31bb2e7..0000000
--- a/src/app/groups/[groupId]/expenses/actions.ts
+++ /dev/null
@@ -1,28 +0,0 @@
-'use server'
-import { createExpense, deleteExpense, updateExpense } from '@/lib/api'
-import { expenseFormSchema } from '@/lib/schemas'
-import { revalidatePath } from 'next/cache'
-
-export async function createExpenseAction(groupId: string, values: unknown) {
- 'use server'
- const expenseFormValues = expenseFormSchema.parse(values)
- await createExpense(expenseFormValues, groupId)
- revalidatePath(`/groups/${groupId}`, 'layout')
-}
-
-export async function updateExpenseAction(
- groupId: string,
- expenseId: string,
- values: unknown,
-) {
- 'use server'
- const expenseFormValues = expenseFormSchema.parse(values)
- await updateExpense(groupId, expenseId, expenseFormValues)
- revalidatePath(`/groups/${groupId}`, 'layout')
-}
-
-export async function deleteExpenseAction(groupId: string, expenseId: string) {
- 'use server'
- await deleteExpense(expenseId)
- revalidatePath(`/groups/${groupId}`, 'layout')
-}
diff --git a/src/app/groups/[groupId]/expenses/create/page.tsx b/src/app/groups/[groupId]/expenses/create/page.tsx
new file mode 100644
index 0000000..e603e59
--- /dev/null
+++ b/src/app/groups/[groupId]/expenses/create/page.tsx
@@ -0,0 +1,27 @@
+import { ExpenseForm } from '@/components/expense-form'
+import { createExpense, getGroup } from '@/lib/api'
+import { expenseFormSchema } from '@/lib/schemas'
+import { Metadata } from 'next'
+import { notFound, redirect } from 'next/navigation'
+
+export const metadata: Metadata = {
+ title: 'Create expense',
+}
+
+export default async function ExpensePage({
+ params: { groupId },
+}: {
+ params: { groupId: string }
+}) {
+ const group = await getGroup(groupId)
+ if (!group) notFound()
+
+ async function createExpenseAction(values: unknown) {
+ 'use server'
+ const expenseFormValues = expenseFormSchema.parse(values)
+ await createExpense(expenseFormValues, groupId)
+ redirect(`/groups/${groupId}`)
+ }
+
+ return <ExpenseForm group={group} onSubmit={createExpenseAction} />
+}
diff --git a/src/app/groups/[groupId]/expenses/expense-list.tsx b/src/app/groups/[groupId]/expenses/expense-list.tsx
index adc6e7a..798a5f8 100644
--- a/src/app/groups/[groupId]/expenses/expense-list.tsx
+++ b/src/app/groups/[groupId]/expenses/expense-list.tsx
@@ -33,9 +33,7 @@ export function ExpenseList({
expense.isReimbursement && 'italic',
)}
onClick={() => {
- router.push(`/groups/${groupId}/expenses/${expense.id}/edit`, {
- scroll: false,
- })
+ router.push(`/groups/${groupId}/expenses/${expense.id}/edit`)
}}
>
<div>
@@ -68,10 +66,7 @@ export function ExpenseList({
{currency} {(expense.amount / 100).toFixed(2)}
</div>
<Button size="icon" variant="link" className="-my-2" asChild>
- <Link
- href={`/groups/${groupId}/expenses/${expense.id}/edit`}
- scroll={false}
- >
+ <Link href={`/groups/${groupId}/expenses/${expense.id}/edit`}>
<ChevronRight className="w-4 h-4" />
</Link>
</Button>
diff --git a/src/app/groups/[groupId]/expenses/expense-page.tsx b/src/app/groups/[groupId]/expenses/expense-page.tsx
deleted file mode 100644
index 281c38b..0000000
--- a/src/app/groups/[groupId]/expenses/expense-page.tsx
+++ /dev/null
@@ -1,19 +0,0 @@
-import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
-import { ReactNode } from 'react'
-
-export function ExpensePage({
- children,
- title,
-}: {
- children: ReactNode
- title: ReactNode
-}) {
- return (
- <Card>
- <CardHeader>
- <CardTitle>{title}</CardTitle>
- </CardHeader>
- <CardContent>{children}</CardContent>
- </Card>
- )
-}
diff --git a/src/app/groups/[groupId]/expenses/layout.tsx b/src/app/groups/[groupId]/expenses/layout.tsx
deleted file mode 100644
index cd65df9..0000000
--- a/src/app/groups/[groupId]/expenses/layout.tsx
+++ /dev/null
@@ -1,9 +0,0 @@
-import { ReactNode } from 'react'
-
-export default function GroupExpensesLayout({
- children,
-}: {
- children: ReactNode
-}) {
- return <>{children}</>
-}
diff --git a/src/app/groups/[groupId]/expenses/page.tsx b/src/app/groups/[groupId]/expenses/page.tsx
index 64987a3..5285cb8 100644
--- a/src/app/groups/[groupId]/expenses/page.tsx
+++ b/src/app/groups/[groupId]/expenses/page.tsx
@@ -35,7 +35,7 @@ export default async function GroupExpensesPage({
</CardHeader>
<CardHeader>
<Button asChild size="icon">
- <Link href={`/groups/${groupId}/expenses/create`} scroll={false}>
+ <Link href={`/groups/${groupId}/expenses/create`}>
<Plus />
</Link>
</Button>
diff --git a/src/app/groups/[groupId]/layout.tsx b/src/app/groups/[groupId]/layout.tsx
index 40f6155..3e649e7 100644
--- a/src/app/groups/[groupId]/layout.tsx
+++ b/src/app/groups/[groupId]/layout.tsx
@@ -5,13 +5,12 @@ import { getGroup } from '@/lib/api'
import { Metadata } from 'next'
import Link from 'next/link'
import { notFound } from 'next/navigation'
-import { PropsWithChildren, ReactNode } from 'react'
+import { PropsWithChildren } from 'react'
type Props = {
params: {
groupId: string
}
- modal: ReactNode
}
export async function generateMetadata({
@@ -29,7 +28,6 @@ export async function generateMetadata({
export default async function GroupLayout({
children,
- modal,
params: { groupId },
}: PropsWithChildren<Props>) {
const group = await getGroup(groupId)
@@ -49,7 +47,6 @@ export default async function GroupLayout({
</div>
{children}
- {modal}
<SaveGroupLocally group={{ id: group.id, name: group.name }} />
</>
diff --git a/src/app/groups/[groupId]/not-found.tsx b/src/app/groups/[groupId]/not-found.tsx
deleted file mode 100644
index af3788b..0000000
--- a/src/app/groups/[groupId]/not-found.tsx
+++ /dev/null
@@ -1,5 +0,0 @@
-'use client'
-
-export default function NotFound() {
- return null
-}
diff --git a/src/app/groups/[groupId]/reimbursement-list.tsx b/src/app/groups/[groupId]/reimbursement-list.tsx
index 1153b59..54ee9d7 100644
--- a/src/app/groups/[groupId]/reimbursement-list.tsx
+++ b/src/app/groups/[groupId]/reimbursement-list.tsx
@@ -37,7 +37,6 @@ export function ReimbursementList({
<Button variant="link" asChild className="-mx-4 -my-3">
<Link
href={`/groups/${groupId}/expenses/create?reimbursement=yes&from=${reimbursement.from}&to=${reimbursement.to}&amount=${reimbursement.amount}`}
- scroll={false}
>
Mark as paid
</Link>