diff --git a/resources/js/components/transactions/edit-transaction-dialog.test.tsx b/resources/js/components/transactions/edit-transaction-dialog.test.tsx
index c287bb16..b5dc4277 100644
--- a/resources/js/components/transactions/edit-transaction-dialog.test.tsx
+++ b/resources/js/components/transactions/edit-transaction-dialog.test.tsx
@@ -1,4 +1,4 @@
-import { render, screen } from '@testing-library/react';
+import { fireEvent, render, screen } from '@testing-library/react';
import type React from 'react';
import { beforeEach, describe, expect, it, vi } from 'vitest';
import { EditTransactionDialog } from './edit-transaction-dialog';
@@ -342,4 +342,92 @@ describe('EditTransactionDialog', () => {
expect(screen.queryByRole('checkbox')).not.toBeInTheDocument();
});
+
+ const manualTransaction = {
+ id: 'tx-manual',
+ user_id: 'user-1',
+ account_id: 'account-1',
+ category_id: null,
+ description: 'Groceries',
+ description_iv: null,
+ transaction_date: '2026-05-27',
+ amount: -1200,
+ currency_code: 'EUR',
+ notes: null,
+ notes_iv: null,
+ creditor_name: null,
+ debtor_name: null,
+ source: 'manually_created' as const,
+ created_at: '2026-05-27T00:00:00Z',
+ updated_at: '2026-05-27T00:00:00Z',
+ decryptedDescription: 'Groceries',
+ decryptedNotes: null,
+ label_ids: [],
+ };
+
+ it('closes the dialog and asks the parent to delete when Delete is clicked', () => {
+ const onDelete = vi.fn();
+ const onOpenChange = vi.fn();
+
+ render(
+ ,
+ );
+
+ fireEvent.click(screen.getByRole('button', { name: 'Delete' }));
+
+ expect(onOpenChange).toHaveBeenCalledWith(false);
+ expect(onDelete).toHaveBeenCalledWith(manualTransaction);
+ });
+
+ it('hides the Delete button when no onDelete handler is provided', () => {
+ render(
+ ,
+ );
+
+ expect(
+ screen.queryByRole('button', { name: 'Delete' }),
+ ).not.toBeInTheDocument();
+ });
+
+ it('hides the Delete button in create mode', () => {
+ render(
+ ,
+ );
+
+ expect(
+ screen.queryByRole('button', { name: 'Delete' }),
+ ).not.toBeInTheDocument();
+ });
});
diff --git a/resources/js/components/transactions/edit-transaction-dialog.tsx b/resources/js/components/transactions/edit-transaction-dialog.tsx
index db8a673a..8852db7b 100644
--- a/resources/js/components/transactions/edit-transaction-dialog.tsx
+++ b/resources/js/components/transactions/edit-transaction-dialog.tsx
@@ -42,6 +42,7 @@ import { formatDate } from '@/utils/date';
import { __ } from '@/utils/i18n';
import { router } from '@inertiajs/react';
import { getYear, parseISO } from 'date-fns';
+import { Trash2 } from 'lucide-react';
import { useEffect, useState } from 'react';
import { toast } from 'sonner';
@@ -61,6 +62,7 @@ interface EditTransactionDialogProps {
source: 'edit_transaction_modal',
) => void;
onLabelCreated?: (label: Label) => void;
+ onDelete?: (transaction: DecryptedTransaction) => void;
mode: 'create' | 'edit';
initialAccountId?: string | null;
}
@@ -77,6 +79,7 @@ export function EditTransactionDialog({
onSuccess,
onCategorized,
onLabelCreated,
+ onDelete,
mode,
initialAccountId = null,
}: EditTransactionDialogProps) {
@@ -867,6 +870,21 @@ export function EditTransactionDialog({
+ {mode === 'edit' && onDelete && transaction && (
+
+ )}
diff --git a/resources/js/pages/transactions/index.tsx b/resources/js/pages/transactions/index.tsx
index 2fba0680..069266f7 100644
--- a/resources/js/pages/transactions/index.tsx
+++ b/resources/js/pages/transactions/index.tsx
@@ -1542,6 +1542,7 @@ export default function Transactions({
onSuccess={updateTransaction}
onCategorized={showAutomatizeToast}
onLabelCreated={handleLabelCreated}
+ onDelete={setDeleteTransaction}
mode="edit"
/>